Practical Web services in IBM Lotus Domino 7: Writing and testing simple Web services

In the second article in our Web services series, we show you how to write simple Web services in IBM Lotus Domino V7.0 that accept and return simple data types, arrays, and InOut parameters. We also discuss several test methods, using tools such as soapUI, Eclipse, MSSOAP toolkit, and Apache Axis.

Share:

Julian Robichaux, Developer, Independent Consultant

Julian Robichaux is a software developer and professional programmer specializing in IBM Lotus Notes and Java development. He is available for hire on small and large projects involving development, architecture, and training. In his spare time, he adds to his personal Web site/blog at http://www.nsftools.com. His family can't understand why he takes his laptop with him everywhere. He doesn't quite understand it either.



21 November 2006 (First published 14 November 2006)

Also available in Chinese Russian

So you want to write a Web service. Great! If you read our first article, "Practical Web services in IBM Lotus Domino 7: What are Web services and why are they important?, you have a good understanding of what Web services are and why they are important. Starting with IBM Lotus Domino V7.0, you can very easily create your own Web services that other clients or systems can consume. In some ways, it's just as easy as writing an agent.

While IBM Lotus Domino Designer allows you to write a Web service using either LotusScript or Java, all the examples in this article are written in LotusScript. However, the example database available with this article (see the Downloads section) has example Web services written in both LotusScript and Java for reference.

Some quick background

Lotus Domino V7.0 introduced the new Web service design element in Lotus Domino Designer. If you open a database in the Lotus Domino Designer V7.0 client, you see the Web Services entry just below the familiar Agents entry in the Shared Code section of the design element tree (see figure 1).

Lotus Domino deals with all the WSDL creation and SOAP handling for you, so all you have to do is write code in your Web service design element as though you were coding an agent. As long as you specify which class to use as the interface class for the service, Lotus Domino can publish a WSDL file, can convert incoming SOAP requests to method calls on your class, and can return the results of your method (if any) as a SOAP response.

From the coding standpoint, all you do is write a LotusScript or Java class. Lotus Domino does the rest!


Writing a simple Web service

Let's write a quick Web service. To create a new Web service, open a database in Lotus Domino Designer, go to the Web Services section of the database design, and click the New Web Service button (see figure 1).

Figure 1. Web Service design element section in Lotus Domino Designer
Web Service design element section in Lotus Domino Designer

A screen very similar to the window you see when you create a new agent opens (see figure 2). In the Web Services Properties box, give the new Web service a name -- we use EchoTestService for this example -- and close the box. We discuss the individual fields on the Properties box shortly.

Figure 2. Web Service design element in Lotus Domino Designer
Web Service design element in Lotus Domino Designer

Now you should have a screen that looks very much like one used for writing a LotusScript agent. Click (Declarations) in the Objects tab of LotusScript events, so you can write a class (classes must always be defined in the (Declarations) section). Enter this code into the IDE:

Listing 1. A very simple Web service that echoes a string
Class EchoTest
	Public Function Echo (txt As String) As String
		Echo = txt
	End Function
End Class

This code does the following:

  • Creates a class called EchoTest.
  • Defines a method in the class called Echo that accepts a string as a parameter and returns a string as a result (functions and subs in classes are referred to as methods).

The Echo method of EchoTest takes a string as a parameter, and it returns the same string. Let's see if this is a valid Web service. Try to save and close the service. You receive the following error:

The Web Service has been saved, but is not valid: 
Please specify which class exposes your Web service interface(s), 
using the 'PortType class' field of the Web Service properties panel.

To avoid this error, open the Web Service Properties box and specify which class to use. Because there may be multiple classes defined in the Web service code, you must select only one of them as an interface to the Web service. The interface class is the one with Public methods that Web service clients can call.

In the Properties box, enter EchoTest (the name of the class you just wrote) in the PortType class field on the first tab. Close the box and try to save and close the Web service again. This time it should work. You now have a working Web service!


The Web Service Properties box

Let's open both the Web service and the Web Service Properties box again. The first tab on the box (the Basics tab) looks like figure 3.

Figure 3. Basics tab of the Web Service Properties box
Basics tab of the Web Service Properties box

The fields on the Basic tab are:

  • Name (required). This is the name of the Web service, and the name that is used when clients access the WSDL file or the methods of the service.
  • Alias. This is an alternative name with which users can access the service, in addition to the Name.
  • Comment. This is simply a field for informational data about the Web service (normally, there shouldn't be more than a sentence of information in this field; long descriptions or information about the Web service should be written in the comments of the code).
  • Warn if the WSDL interface is modified. This option warns you if code changes you make alter the WSDL file produced by the Web service. This can be useful if you want to make sure that the WSDL file remains consistent, but be aware that you cannot save a service with a modified WSDL file if this option is selected.
  • PortType class (required). This is the name of the class that is used as the Web service interface. In other words, it's the class in the Web service code with public methods that users can access.

The second tab on the box is the Security tab (see figure 4).

Figure 4. Security tab of the Web Service Properties box
Security tab of the Web Service Properties box

The fields on the Security tab are:

  • Run as web user. This option enables the Web service code to run under the security context of the user who calls the Web service (by default, it runs under the security context of the ID that last signed the Web service in Lotus Domino Designer).
  • Run on behalf of. This field lets you specify a user if you want the Web service code to run under the security context of a specific user, instead of the security context of the ID that last signed the Web service in Lotus Domino Designer.
  • Allow remote debugging. This option allows remote debugging of the Web service (see the Lotus Domino Designer Help topic, "Using the Remote Debugger," for information about remote debugging).
  • Profile this web service. This option causes the Web service to generate profiling information when it runs (see the Lotus Domino Designer Help topic, "Profiling agents and Web services," for information about profiling).
  • Set runtime security level. A setting of 1 allows most LotusScript and Java operations to run properly; a setting of 2 or 3 is needed for operations such as read/write files, create COM objects, or perform network operations (see the Lotus Domino Designer Help topic, "Restricted LotusScript and Java agent operations," for more information).
  • Default access for this web service. This option allows you to control which users can access the Web service beyond what is controlled by the database ACL (if Anonymous users cannot access a Web service, they receive an error 401 Access Denied or 404 Not Found when trying to connect to it).
  • Allow Public Access users to use this web service. This option allows users with only "Read Public Documents" access in the database ACL to use this Web service, which is useful if you don't want to grant full Reader access (or higher) to a large number of users.

The third tab on the box is the Options tab (see figure 5).

Figure 5. Options tab of the Web Service Properties box
Options tab of the Web Service Properties box

The fields on the Options tab are:

  • Programming model. The options are RPC or Message (you almost always want to use RPC).
  • SOAP message format. In this field, you choose a SOAP message format for this Web service (see more information about formats in the next section). The default format in Lotus Domino V7.0 is RPC/encoded.
  • Include operation name in SOAP action. This option requires the operation name to reside in the SOAP action header of incoming requests (rarely, if ever, needed).
  • Port type name. By default, this field value is the same one specified in the PortType class field on the Basics tab (although you can use any name you want). Used when generating the WSDL file.
  • Service element name. By default, this field value is the same as the port type name with the word Service appended to it (although you can use any name you want). Used when generating the WSDL file.
  • Service port name. This field value is Domino by default, although you can use any name you want. Used when generating the WSDL file.

As you can see, there are a number of properties that you can set, although the only required ones are the Web service name and the port type class. All other properties are either optional or have a suitable default value.

SOAP message formats

There are a number of different SOAP message formats to choose from in the Web Service Properties box, and it may be difficult to decide which one to use. The different formats create slightly different WSDL files, which in turn produce slightly different SOAP requests and responses.

From the coding standpoint, you notice no difference because you write the Web services exactly the same no matter which format you use. However, it may make a difference to the user clients that make calls to your Web service.

In general, RPC/encoded is a format that is more widely understood by older Web service client technologies, such as Apache SOAP and MSSOAP. Doc/literal is used by default by Microsoft .NET clients and servers and has been gaining in popularity in the past few years.

Your choice of message format relies on the technology used by the clients that call the service and which SOAP format is easiest to use with that client technology. If you have no control over the clients that call your service, RPC/encoded and Doc/literal are both good choices.

For a good explanation of the different formats and how they affect WSDL structure and SOAP messages, see the often quoted developerWorks article, "Which style of WSDL should I use?."


Web service classes using simple data types

Let's get back to writing Web service code. You know that the LotusScript code that is exposed as a Web service needs to be written as a class. Virtually any function or sub that you would normally write in LotusScript works as a class method in a Web service with the following restrictions:

  • Do not use native LotusScript classes (such as NotesDatabase, NotesDocument, and so on) as parameters or return values.
  • Do not use variants or the currency data type as parameters or return values.
  • Do not use lists or arrays as parameters or return values (arrays are possible, but you must use a special data type described later in this article).
  • Do not use custom types as parameters or return values.

Conversely, you can use the following as parameters or return values in a Web service class method:

  • Simple data types (string, integer, and so on)
  • Custom user-defined classes
  • Special classes defined in the lsxsd.lss file (included in the Lotus Notes/Domino V7.0 client and server files)

The user-defined classes appear as complex data types, which we discuss in the next article. The classes in the lsxsd.lss file (which can be found in your local Notes program directory) are very useful and can allow you to pass string arrays, files, and dates. We discuss some of these classes later in this article and some of them in the next article.

For now, let's see some examples of using simple data types in your classes. Consider the following class:

Listing 2. A LotusScript Web service with several methods
Class DatabaseInfo
	Private session As NotesSession
	Private db As NotesDatabase
	
	Public Sub New ()
		Set session = New NotesSession
		Set db = session.CurrentDatabase
	End Sub
	
	Public Function GetDbName () As String
		GetDbName = db.Title
	End Function
	
	Public Sub UpdateFTIndex ()
		Call db.UpdateFTIndex(True)
	End Sub
	
	Public Function GetUserRoles (userName As String) As String
		GetUserRoles = Join(getRoles(userName), ",")
	End Function
	
	Private Function getRoles (userName As String) As Variant
		Dim acl As NotesACL
		Dim entry As NotesACLEntry
		Dim sep As String
		
		Set acl = db.ACL
		Set entry = acl.GetEntry(userName)
		
		If (entry Is Nothing) Then
			Dim returnArray(0) As String
			getRoles = returnArray
		Else
			getRoles = entry.Roles
		End If
	End Function
End Class

The code is straightforward, but note the following about the various methods:

  • New. The New method is optional and is not available to clients that call the Web service. It is simply used for initialization code, if any is needed. Also, if you write a New method, it must be a sub, and it must not take any parameters.
  • GetDbName. The GetDbName method does not take any parameters. This is legal.
  • UpdateFTIndex. The UpdateFTIndex method takes no parameters and returns no values. This is also legal.
  • GetUserRoles. The GetUserRoles method calls another method to do most of the work. You can also call other functions and subs (outside of the class), and you can even call classes, functions, and subs from script libraries that are referenced with a Use statement. This is very useful because not only can it keep the Web service code concise, but also it can help to separate the Web service code from any business logic code you already have.
  • getRoles. The getRoles method has been declared Private, so it can be used by other methods in the class, but it is not available for use by clients that call the Web service. Declaring some methods Private is a good way to keep code and logic inside a class while not allowing it to be called directly by a user.

    Keep in mind, though, that if a method is not declared either Public or Private, it is available as a Public method.

So far, there's nothing really complicated here. You decide which functions/subs a user can call, and you wrap them inside of a class as methods. You can also reference other classes, functions, and subs from script libraries if the code or logic you require has already been written.


Returning arrays

You may have noticed that the GetUserRoles method converted the array of strings that was returned by the getRoles method into a single delimited string before it returned the value. This is because you cannot return a LotusScript array directly from a Web service, either as an array or as a variant.

However, you can return an array by returning an instance of one of the ARRAY_HOLDER classes from the lsxsd.lss file. The ARRAY_HOLDER classes (STRINGARRAY_HOLDER, INTEGERARRAY_HOLDER, and so on) are automatically transformed into SOAP-friendly arrays when they are returned as values.

As an example, you could add the line %INCLUDE "lsxsd.lss" to the (Options) section of the Web service and rewrite the GetUserRoles method like this:

Listing 3. Returning a string array in a LotusScript Web service
	Public Function GetUserRolesArray (userName As String) As STRINGARRAY_HOLDER
		Dim returnArray As New STRINGARRAY_HOLDER
		Dim roles As Variant
		Dim i As Integer
		
		roles = getRoles(userName)
		Redim returnArray.Value(Ubound(roles))
		For i = 0 To Ubound(roles)
			returnArray.Value(i) = roles(i)
		Next
		
		Set GetUserRolesArray = returnArray
	End Function

As far as the user's client is concerned, the GetUserRolesArray method returns a normal string array rather than a special STRINGARRAY_HOLDER object. This is because the Domino Web service performs the translation between STRINGARRAY_HOLDER and a string array in the background when the service is accessed. You have to do a little extra work to add the elements of the getRoles array into the Value member of the STRINGARRAY_HOLDER (because you cannot set the Value directly equal to another array), but it's just a few lines of code.

Of course, string arrays are not the only kind of arrays you can accept or return. There are also INTEGERARRAY_HOLDER, LONGARRAY_HOLDER, and similar classes defined in the lsxsd.lss file that provide the same functionality for other native data types. See the Lotus Domino Designer Help or the lsxsd.lss file for more information.

Another option for returning arrays is to return them as parts of a complex data type, which is a technique we discuss in the next article.


Returning multiple values with InOut parameters

A different technique you can use when you want to work with only simple data types is InOut parameters. These are parameters that can both receive a value for input and return a value for output. For example, consider the following class:

Listing 4. Using InOut parameters in a LotusScript Web service
Class InOutTest
	Public Sub AddOne (inout As INTEGER_HOLDER)
		inout.Value = inout.Value + 1
	End Sub
	
	Public Function SwapAndAdd (inout1 As INTEGER_HOLDER, _
	inout2 As INTEGER_HOLDER) As Integer
		SwapAndAdd = inout1.Value + inout2.Value
		inout1.Value = inout2.Value
		inout2.Value = SwapAndAdd - inout2.Value
	End Function
End Class

The first method (AddOne) takes an integer as an input parameter. The code in the method adds one to the value that was passed and -- because it is an INTEGER_HOLDER -- it returns the new value back in the SOAP response.

This is a special property of the HOLDER classes that are defined in the lsxsd.lss file. When they are used as method parameters, they become InOut parameters in the SOAP request/response, so they both receive and return a value.

The AddOne method is not a very practical example because you would normally just receive a regular integer as a parameter and write the method as a function that returns a modified integer. However, if you have one or more InOut parameters as well as a method return value, you now have the ability to return multiple individual values in your method response instead of a single value.

Let's look at the second method called SwapAndAdd. This method has two InOut values as parameters, and it returns an integer. On the user client, they generate a SOAP request that sends two integer values as parameters and receive a SOAP request with three integer values in the response: the two values that were passed as parameters (and modified by the method) and the result.

Admittedly, InOut parameters are not seen that often because returning multiple values is normally handled by returning complex data types, but it is a good technique to be aware of. Again, we will talk about complex data types in the next article in this series.


Working with dates and times

One last simple data type that you may need to work with is a date/time object. Here's an example of using date/time values in parameters and return objects:

Listing 5. Using dates and times in a LotusScript Web service
Class DateTester
	Public Function getCurrentTime () As XSD_DATETIME
		Dim dt As New NotesDateTime(Now)
		Set getCurrentTime = New XSD_DATETIME
		Call getCurrentTime.SetValueFromNotesDateTime(dt)
	End Function
 	
	Public Function getLocalDateFormat (xdt As XSD_DATETIME) As String
		Dim dt As NotesDateTime
		Set dt = xdt.GetValueAsNotesDateTime()
		getLocalDateFormat = dt.LocalTime
	End Function
End Class

Once again, the lsxsd.lss classes come to the rescue. You can simply receive or return a variable of type XSD_DATETIME (which becomes a SOAP dateTime element) and convert it to or from a NotesDateTime object.

Be aware, however, that the time zone handling of time values can be difficult sometimes because servers and clients may or may not add or interpret time zone offsets of the SOAP dateTime elements properly. A recent W3C Note discusses some aspects of this problem. As always, you should attempt to test thoroughly with your Web service clients first.


Testing your Web service

Testing Web services on local databases

If you have a local copy of a database with a Web service that you want to test, make sure that the Notes HTTP service is running in the background first. The easiest way to do that is to:

  1. Open the database in Lotus Domino Designer.
  2. Select a Form or View in the database.
  3. Choose Design - Preview in Web Browser - Default Browser and wait for the form or view to appear in a Web browser.

After you see the form or view in your Web browser, you can close the browser window and test your Web service. The HTTP service continues to run in the background until you close the Notes client completely. Some personal firewalls block the operation of the local HTTP service, so you may have to adjust your firewall settings.

Now that you have written a Web service, you certainly want to test it. To access the WSDL of your Web service, you need to use the full URL path of the Web service with the ?WSDL URL command at the end.

For example, for a database called WSTest.nsf on a server with a DNS name of mydomino.example.com with a Web service called MyNewWebService, you use the following URL:

http://mydomino.example.com/WSTest.nsf/MyNewWebService?WSDL

There are a number of Web service testing tools available for testing -- both free and commercial -- and a long article or tutorial could easily be written describing various testing methods.

Below are several free tools that you can use for testing and calling a Web service with a brief description of each. Understanding the details of each tool is an exercise left to the reader.

soapUI

One of the easiest-to-use tools for testing a Web service is soapUI available from the soapUI Web site. SoapUI is a free desktop program written in Java, so it can run on several different operating systems. Here are the steps to testing a Web service with it:

  1. Make sure you have Java 1.5 or later installed properly on your local machine.
  2. Download the soapUI program and unzip the downloaded file.
  3. In the /bin directory of the unzipped files, run either the soapui.bat file (on Windows machines) or the soapui.sh file (on other operating systems) to open soapUI.
  4. Choose File - New WSDL Project and enter a name for the project when prompted.
  5. Right-click the new project in the list of projects in the left-hand navigator, and choose the "Add WSDL From URL" option.
  6. Enter the URL of your test service (for example, http://localhost/DWSTest.nsf/EchoTestService?WSDL), and click Yes if you are prompted to create default requests for all operations.
  7. You should now be able to completely expand the new project on the left and see an entry for each Web service method that is available to be called. If you double-click the Request entry beneath a method name, you see a pre-constructed SOAP request that can be sent as a test (see figure 6).
    Figure 6. soapUI interface
    soapUI interface
  8. For the EchoTest service seen in figure 6, we have a simple SOAP request to send. If you want to test the service, enter text in the <TXT> node of the request envelope and click the green arrow button in the toolbar just above the SOAP request text. This sends the request to the service and displays the resulting SOAP response in the right-hand pane.

SoapUI allows you to build test suites that are suitable for unit-testing your Web service. This way, you can create a set of tests, and whenever you make changes to your Web service, you can run the pre-written tests to ensure that everything still works properly.

The downside is that you have to do everything through raw XML SOAP requests and responses. If you are comfortable with XML and SOAP, this isn't difficult because the hard part (writing the SOAP requests in the first place) has been done for you, and you can see exactly how the SOAP responses look. However, if you prefer to work at a more abstract level -- using simple APIs or function calls within a program perhaps -- this tool may be too low level for you.

Eclipse and the Web Tools Platform (WTP)

If you have Eclipse installed (or want an excuse to use Eclipse), there is a very nice package called the Web Tools Platform (WTP) that provides a higher-level interface for testing your Web service. Instead of working with raw SOAP requests, WTP can create a form for each of your Web service methods, allowing you to simply enter values into the form and send the request.

Here are the basic steps for installing and using the WTP:

  1. Download and install the Eclipse platform.
  2. Install the WTP components. For Eclipse versions prior to 3.2, see the installation instructions on the WTP Web site. For Eclipse 3.2 or later, these instructions are part of the Callisto toolkit under the "Web and J2EE Development" section. Do the following:
    1. Choose Help - Software Updates - Find and Install.
    2. On the next screen, choose "Search for new features to install," and then click Next.
    3. Make sure that the Callisto Discovery Site option is selected and click Next.
    4. Beneath the Callisto Discovery Site section on the list of packages to install, select the "Web and J2EE Development" item (which also selects all items beneath it). Then click the Select Required button to get all other required components, and click Next to install (see figure 7). Installation takes several minutes.
    Figure 7. WST package installation in Eclipse
    WST package installation in Eclipse
  3. After you finish the installation, restart Eclipse. From the main Workbench page, choose Run - Launch the Web Services Explorer.
  4. In the Web Services Explorer view, click the WSDL Page button so that WSDL Main is added to the Navigator pane (see figure 8).
    Figure 8. WSDL Explorer in WST
    WSDL Explorer in WST
  5. You can enter a WSDL path in the Actions pane. Enter the URL of your test service (for example, http://localhost/DWSTest.nsf/EchoTestService?WSDL), and click the Go button.
  6. After the WSDL file is found, you should now have a tree structure beneath the WSDL Main item in the Navigator pane, listing all the methods in your Web service.
  7. Double-click any of the method names in the WSDL tree to bring up a form in the Actions pane that allows you to enter values for each parameter in the method and sends them to the Web service. The response is displayed in the Status pane at the bottom (see figure 9).
    Figure 9. SOAP request in WST
    SOAP request in WST
  8. If you want to see the raw XML SOAP messages that were sent and received by the Web service call, click the Source link in the Status pane.

While the initial setup for the Eclipse WTP is more complex than the soapUI tool, it provides a more user friendly interface (forms instead of raw requests). If you need lower-level detail, you can still see the raw messages that are sent and received, but some people find it easier to work with the forms-based approach to creating and sending the requests.

MSSOAP toolkit

Many LotusScript programmers who use the Windows platform have been successful in using the MSSOAP toolkit to make Web service calls. While this toolkit is no longer supported or updated by Microsoft (it has been superseded by the Microsoft .NET framework), it is such a common technique that it is worth mentioning here.

MSSOAP is a DLL file that can either be downloaded from Microsoft or is already on the workstation as part of your standard Windows installation. You can make calls to the DLL as a COM object using LotusScript similar to this:

Listing 6. Simple MSSOAP calls from LotusScript
Dim Client As Variant
Set Client = CreateObject("MSSOAP.SoapClient")
Call Client.MSSoapInit("http://localhost/DWSTest.nsf/EchoTestService?WSDL")
Print "Echo said " & Client.Echo("echo")

Obviously, you need to have some knowledge of the methods in the Web service and the parameters and data types that are used. If you call another Web service, you can either read and interpret the WSDL file manually (which can be painful) or use a tool like soapUI or the Eclipse WTP to translate everything for you.

Unfortunately, the version of MSSOAP that is normally found on a Windows machine is version 1.x, which only works well with RPC/Encoded Web services that use simple data types as parameters. When complex data types are returned, they are usually IXMLDOMNodeList objects, but passing complex data types as parameters requires the creation of new IXMLDOMNodeList objects and can be tricky. Also, MSSOAP 1.x generally cannot understand Web services that use enumerations (which is something we discuss in the next article in this series).

If you have control over the servers or workstations that use the MSSOAP library, you have the option of downloading and installing the SOAP Toolkit version 3.0, which lets you call a wider variety of Web services. After you install the toolkit, you can change the code above from CreateObject("MSSOAP.SoapClient") to CreateObject("MSSOAP.SoapClient30") to use the newer version of the library. Table 1 lists the differences between the two different versions.

Table 1. Differences between MSSOAP 1.x and 3.0
MSSOAP 1.xMSSOAP 3.0
On most Windows XP/2000 machines by defaultMust be downloaded and installed
CreateObject("MSSOAP.SoapClient")CreateObject("MSSOAP.SoapClient30")
RPC/Encoded Web services onlyRPC/Encoded, RPC/Literal, Doc/Literal, Wrapped
Enumerations are not understoodEnumerations from LotusScript Web services are okay, although enumerations returned from Java Web services may not be interpreted properly

MSSOAP allows dynamic calls to Web services (which can be convenient), and there are a lot of code examples for using MSSOAP (both in LotusScript and Visual Basic, which is easily converted to LotusScript), so if you call Web services from a Windows machine, it is a nice option to use.

Apache Axis

In a Lotus Notes environment, the Apache Axis framework is another good option for calling a Web service. Axis is a very mature Java package that has been used for creating, providing, and consuming Web services for many years on many different platforms. In fact, a version of Axis is the underlying technology that allows Lotus Domino V7 to provide Web services!

If you use Axis to call a Web service as a client, you normally use a Java command-line tool (which comes with Axis) called wsdl2java to create stub files for calling the Web service, based on the service's WSDL file. These stub files are Java classes that act as wrappers around the complex code that is required to access and use the Web service, so all you have to do is use the stub class to call the method and return the response. While you have to do the frontend work of generating the stub files for any Web services you want to call, you are also spared the trouble later on of having to understand the intricacies of the Web service (the SOAP message format, the namespaces, the response parsing, and so on).

If you want to use Apache Axis to write code in Lotus Notes to call a Web service, two good places to start are the developerWorks article, "Consuming Web services from a Lotus Domino Java agent," and the open source Stubby database that is available on the OpenNTF Web site. As an example, here's how you can use Stubby to create Axis code that calls our EchoTest service:

  1. Download the Stubby database from OpenNTF.org and open it in a Lotus Notes V7 client.
  2. Click the Create New Doc button to create a new document in the database, and enter the URL of our EchoTest service (http://localhost/DWSTest.nsf/EchoTestService?WSDL) in the WSDL File field on the form (see figure 10).
    Figure 10. Stubby database document
    Stubby database document
  3. Click the Generate Stub Files button on the form to create the Axis stub files. This also creates a JAR file that contains all the stub files already compiled and ready to use. All files that are created are attached to fields on the generated files tab of the Stubby document.
  4. Detach the JAR file on the generated files tab (in this case, EchoTestService.jar) to your local file system.
  5. Create a new Java agent in a database using Lotus Domino Designer V7 and attach the JAR file from the previous step using the Edit Project button.
  6. From the sample code tab on the Stubby document, copy the example agent code that was generated and paste it into the agent. You also need to add a line that calls the Echo method of the Web service. The resulting agent code looks something like this (comments and blank lines have been removed for brevity):
    Listing 7. Using Apache Axis stub files in a Lotus Notes Java agent
    import lotus.domino.*;
    import DefaultNamespace.*;
    public class JavaAgent extends AgentBase {
        public void NotesMain() {
            try {
                EchoTestServiceLocator locator = new EchoTestServiceLocator();
                EchoTest service = locator.getDomino();
                System.out.println("Echo said " + service.ECHO("echo"));
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
  7. You can now run the agent on any Lotus Notes/Domino V7 client or server to access the Web service.

There are also examples in the Stubby database of using LS2J to call the Web service stub code with LotusScript for programmers who are more comfortable using LotusScript. For more information about LS2J, see the Lotus Domino Designer Help.

PHP nuSOAP

Another interesting thing you might try when testing your Web service is the PHP nuSOAP library. This is not only very easy to use for consuming a Web service, but it can also give you a nice way to display information about your Domino Web service.

For example, if you have a PHP server available (or if you have a local PHP installation such as WAMP server), you can copy the nuSOAP library to it and create the following page:

Listing 8. Using PHP nuSOAP to get details about a WSDL file
<?php
$wsdlURL = $_POST["wsdlurl"];

if ($wsdlURL) {
	// MODIFY THIS -- make sure the path below is set correctly 
	require_once('../nusoap/lib/nusoap.php');
	
	$wsdlURL = urldecode($wsdlURL);
   	$wsdl = new wsdl($wsdlURL);
	
	$wsdlerror = $wsdl->getError();
	if ($wsdlerror) {
		echo 'There was an error getting the WSDL file at ' .
		htmlspecialchars($wsdlURL) . ':<br>' . $wsdlerror;
	} else {
		echo $wsdl->WebDescription();
	}
} else {
	$htmlPage = '<html>
<head>
<title>nuSoap WSDL Documentation Generator</title>
</head>
<body>
<h3>nuSoap WSDL Documentation Generator</h3>
This page uses the 
<a href="http://sourceforge.net/projects/nusoap/">PHP nuSOAP</a> 
library to generate a nice description of a given WSDL file
and all of its available methods.<p>
<form method="post" action="' . $_SERVER['PHP_SELF'] . '">
Please enter the URL of your WSDL file below:<br>
<input type="text" size="75" name="wsdlurl"><p>
<input type="submit" value="submit" name="submit"><br />
</form>
</body>
</html>';
	
	echo $htmlPage;
}

?>

If you save this page to the PHP server and open it in a browser, you are prompted for the URL location of your WSDL file. By entering the URL and clicking the Submit button, you see a page describing each public method of your Web service (see figure 11).

Figure 11. PHP nuSOAP WSDL documentation example
PHP nuSOAP WSDL documentation example

NOTE: If the Web service is in a database that is on your local machine, you need to run this page from a local installation of a PHP server (again, WAMP server is a very easy one to set up and use), and you need to make sure that the local PHP server does NOT use port 80 (so it doesn't interfere with the local Notes HTTP service).

SoapLog for Domino SOAP message tracking

One other tool you might consider using is the SoapLog DSAPI Filter. This is a DLL file and a Notes database that you can copy to your server, and it records the SOAP messages that are sent to Web services on your server. At the time of this writing, the DLL is for Windows servers only, and the free version of the tool is unsupported.

You can install the SoapLog tool as follows:

  1. Download SoapLog and unzip the downloaded file on your local workstation.
  2. Copy the soaplog.dll file to the Notes program directory on your Domino server.
  3. Copy the SoapLog.nsf database to the data directory on your Domino server, and adjust the ACL as needed (just make sure the server can write to it).
  4. Add the SOAPLOG_DBNAME variable to the server's Notes.ini file, pointing to the SoapLog.nsf database. For example, if the SoapLog.nsf database is in the root data directory, add this line to the Notes.ini file:
    SOAPLOG_DBNAME=SoapLog.nsf
  5. Open the server document for your server in the Domino Directory. On the Internet Protocols - HTTP tab, you see a DSAPI section about halfway down the page on the right. Add an entry for soaplog.dll in this field (if there is already an entry in this field, add a new line before adding the soaplog.dll entry).
  6. Restart the HTTP task on the Domino server. You should see a message indicating that the SoapLog DSAPI has loaded as well.

After the filter is loaded, all SOAP message requests for Web services on your server create new log documents in the SoapLog.nsf database (see figures 12 and 13).

Figure 12. SoapLog request tab
SoapLog request tab
Figure 13. SoapLog response tab
SoapLog response tab

There are also a few additional Notes.ini parameters that you can set to further refine the logging. See the Using This Database document in the SoapLog.nsf database for more information on how it works.


Summary

This article walked you through the steps of creating and testing a simple Web service in Lotus Domino V7. The Domino V7 platform has made it very easy to create and provide Web services, using code that is very much like the code you may already be writing for LotusScript or Java agents. While testing and calling a Web service in Lotus Notes is not as native a process as providing one yet, there are still a number of good options for writing Web service clients that can interact with the services you write.

A huge advantage of this is that other (non-Domino) Web service-enabled systems in your enterprise can easily access and consume the Web services that you write, making Lotus Domino a true player in an SOA environment.

The next article in this series focuses on writing more sophisticated Web services, such as ones that use complex data types, that send and receive file attachments, and that generate custom faults.


Download

DescriptionNameSize
Sample database containing codeDWSTest.nsf1 MB

Resources

Learn

Get products and technologies

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=173275
ArticleTitle=Practical Web services in IBM Lotus Domino 7: Writing and testing simple Web services
publish-date=11212006