HomeDigital EditionSys-Con RadioSearch Web Services Cd
B2B Beginning WS Business Process Management Case Studies Content Management Distributing Computing e-Business Electronic Data Interchange Enterprise Industry Insight Integration Interviews Java & Web Services .NET Portal Product Reviews Scalability & Performance Security SOAP Source Code UDDI Wireless WS Standards WS Tips & Techniques WSDL WS Editorials XML

Source Code for this article

PowerBuilder, a 4GL RAD tool, has extended its productivity to Web services components and application development. With this RAD environment, developers may not only make use of Web services, creating new Web services components and applications, but also easily migrate existing components to Web services. This article discusses how to consume different kinds of Web services in PowerBuilder applications and how to produce PowerBuilder components as Web services in PowerBuilder 9.

Introduction
Web services are loosely defined as the use of Internet technologies to make distributed software programs talk to each other. Programs that want to interact with one another over the Web must be able to find one another. They also must figure out what the expected interaction patterns are, such as what methods the services offer, what data types the services accept, what protocols they can use to communicate with each other, and the quality of services such as security, transaction, and reliable messaging. Then they must have an agreement on messaging systems so they can understand each other.

To meet these requirements, W3C has developed a collection of standards such as Web Services Description Language (WSDL), Simple Object Access Protocol (SOAP), and Universal Description, Discovery, and Integration (UDDI). With these specifications, developers may create and consume Web services as well. However, these specifications are too complex for application developers. PowerBuilder abstracts the complexity and provides a simplified and productive 4GL development environment for developers to use instead.

Building a Web Services Client
PowerBuilder has always been an open development environment for building client-side applications. PowerBuilder 9 allows developers to build a generic client to consume Web services in Windows applications and Web applications. They can make use of any Web services no matter if the services are created in PowerBuilder, .NET, Java, or other third-party tools. In the next two sections, we'll show you how to easily consume Web services in these two kinds of applications. We'll use http://www.xmethods.net/sd/2001/ CurrencyExchangeService.wsdl for the example.

Consuming Web Services in a Windows Application
To consume Web services in PowerBuilder Windows applications, you first need to create a Web Service proxy, which represents the remote Web service. Then you may call the Web service via the proxy in the application. The following steps provide more details.

Step 1: Use Web Service Proxy Wizard to Create a Proxy from WSDL File
In PowerBuilder 9, the Web Service Proxy Wizard helps developers generate the proxy for developing an application. To start the wizard, select the Web Service Proxy Wizard icon from the Project page of the New dialog box. Following the wizard:

  • Specify WSDL file: It may be a local file or a remote file from the Internet. In this sample, we use www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl.
  • Select the service from the service list within the WSDL file.
  • Choose the port or ports to use: Only SOAP ports are supported in PowerBuilder 9. So selecting ports with other type (such as Get, Post) will result in error.
  • Give a prefix that is appended to the port name: It becomes the proxy name.
  • Specify the PowerBuilder library where the proxy will be deployed.
  • Give a project name: It will store the information given above and deploy the proxy.

    Once finished, the wizard will create the project into its current PowerBuilder library. The project looks like Figure 1. Right-click the project in the system tree and select Deploy. The project will generate the proxy automatically. If there are complex types in the WSDL file, the project will generate PB structures for them too. Now the proxy is ready for PowerScript.

    Figure 1

    Step 2: Use the Proxy to Call Web Services
    Invoking Web services through SOAP requires serialization and deserialization of data type, building SOAP messages, and parsing SOAP messages. In PowerBuilder 9, PBSoapClient90.pbd and PBSoapClient90. dll are developed for this task. These two files are installed in the Shared/PowerBuilder directory when PowerBuilder 9 is installed. The PBSoapClient90.pbd must be added into the applications and PBSoap- Client90.dll must be deployed with your application executables. PowerBuilder 9 (GA release) will add PBSoapClient90.pbd into the system tree automatically when you create an application.

    If you're using a beta version, you may need to do this manually. To do so, right-click the application in the system tree and select Properties, then type in the full path and name in the Library List or browse the file from the hard disk.

    There are two classes in PBSoapClient90. pbd, namely SoapConnection and SoapException. The SoapConnection class is used to instantiate the proxy object, populate the SOAP options, and connect to the SOAP server. It has three public methods that we can use immediately.

  • CreateInstance(proxy_object, proxy_classname): Create proxy instance using default endpoint, which is stored in the proxy.
  • CreateInstance(proxy_object, proxy_classname, endpoint): Create proxy instance using the endpoint specified. The default endpoint will be ignored.
  • SetOptions(optionString): Set options for the SoapConnection. There are three options available: SoapLog, UserID, and Password. The string values for the option names are case insensitive. The format for option string is name/value pairs. For example, the option string could be:

    "SoapLog=~"Logpath~", userID=~"username~", Password=~"password~"

    The SoapException class is used to process exception. It inherits from the PowerBuilder Runtime error class. All exceptions and errors during the execution of Web services will be converted to Soap Exception and thrown to calling script. PowerScript can use try-catch black to capture this exception.

    The script in Listing 1 shows you how to invoke Web services in PowerScript. It creates an instance of SoapConnection and sets the options for the connection first. In the example, we only set the SOAP log file to capture the exchanged messages between PowerBuilder client and SOAP server. Then it creates an instance for the proxy. Next, it invokes the method ("get Rate") of the Web service and prints out the result. If anything goes wrong, the script will capture the exception and print out an error message.

    Result
    Now we can run our application; we can see a message box with the correct return value (see Figure 2).

    Figure 2

    It's really simple to build PowerBuilder applications to consume Web services. The sample Web service used here is developed in Java. And we can make use of it in our PowerScript. Besides that, PowerBuilder can also consume Web services that are developed in any other language and run on any Web servers. such as .NET server, Apache, WebLogic, WebSphere, and EAServer. Visit www.xmethods.com for more information or to create your own Web services in PowerBuilder 9.

    Consuming Web services in a JSP Application
    PowerBuilder 9 enables developers to build and use JavaServer Pages (JSPs) in their PowerBuilder Web applications. A JSP application in PowerBuilder 9 may consume Web services as well. Create a JSP target with the source and build folder and deployment configuration first. The JSP may be deployed to EAServer or Tomcat. In this example, we use EAServer. Then we use the JSP Web Service Proxy Wizard on the Web page of the New dialog box to create a custom tag library with the information necessary for calling a Web service in a JSP. The JSP Web Service Proxy Wizard is similar to the Web Service Proxy Wizard for the PowerBuilder Windows application. It collects information such as the location of a WSDL file, the service, and port. We can specify overrides to the WSDL file for a custom bean name, Java class name, Java package name, TLD name, JAR file name, output variables, and the selection of operations within a service. The wizard creates a TLD file, the Java source code to process the custom tag, and the compiled Java class files of the source.

    Once the custom tag is generated, it appears in the system tree. To use custom tags to invoke Web services, do the following:

  • Declare the custom tag library to the JSP page by dragging the TLD file from the Components tab of the system tree to the Page tab of the JSP page. We use "sg" as the prefix. Once it is dragged to the JSP page, the tag library is automatically associated with the page.
  • Declare input arguments for the custom tag in server script if needed.
  • Declare custom tag of Web services to the JSP page by dragging the method of the Web service from the Components tab of the system tree to the Page tab of the JSP page. Specify the input arguments for the custom tags for the Web services in the JSP. We use "US" as country 1 and "Japan" as country 2.
  • Output arguments are stored in the page Context of the JSP container. Its name is "returnValue".
  • Set the properties of the JSP target for deployment and run.
  • Build the JSP pages and deploy WAR files to the EAServer. To do so, right-click the JSP target and select Deploy.

    The TLD file for the currency exchange example used earlier looks like Listing 2 . The source code of the JSP page to call the Web service is shown in Listing 3 . Now run the JSP page in PowerBuilder or browse to the JSP page just deployed. If all went well, the correct exchange rate will show on the page. If anything goes wrong, consult the log file.

    A custom tag for Web services throws a JspTagException for non-recoverable errors if something goes wrong. The JspTag Exception contains information about the root cause of the exception and the point where the error occurred in processing the custom tag. This exception can be caught in a Try-Catch block or mapped to a specific error page in the Deployment Configuration Properties dialog box for the JSP target.

    Note: JSP in PowerBuilder 9 now supports only RPC-style Web services.

    Deploying Web Services in PowerBuilder 9 to EAServer
    PowerBuilder, as a 4GL RAD tool, extends to component and Web service development as well. I'll use EAServer 4.1.3 as both application server and Web server. What follows is a five-step program for developing EAServer components and deploying them to Web services via EAServer. If you already have your PowerBuilder components, you may skip Step 1.

    Step 1: Develop EAServer Component in PowerBuilder 9
    In PowerBuilder, there are several kinds of wizards - such as application, template application, EAServer component, COM/ MTS component, and automation server - to help developers generate PowerBuilder applications. In our case, we chose the EA- Server component. Before running the wizard to generate the EAServer component, the EAServer must be started and the EAServer profile must be created in PowerBuilder.

    We selected the EAServer Component Wizard icon from the Target page of the New dialog box. As you work through the wizard, you'll make the following decisions:

  • Application name: We call it "hello". The PB library and PB target with the same name will be generated automatically.
  • Interface Options: We used new interface.
  • PowerBuilder object name: We used "n_ hello".
  • Component name: To be the component name when deployed to EAServer.
  • Select the EAServer you want to use.
  • Package name: The package name when deployed to the EAServer. We use "p_hel lo".
  • Component type: We use standard type.
  • Determine if the instance pooling will be used.
  • Determine if the component supports transaction
  • Select interface options.
  • Project name: This project will be used to deploy the component.

    For most wizard pages, we use the default values. Once finished, you'll see a PB target named "hello" within the system tree. Under the target, a project ("p_hello_eascomps") and a component ("n_hello") were already created. Now you may develop any functions in the component. The following function is an example:

    function string f_hello (string name)
    return string("Hello, Web services from") + string(name)
    end function

    Step 2: Deploy PowerBuilder Object to EAServer
    Once the development of the component is finished, right-click the project ("p_hello_eascomps") and select Deploy to deploy the component to EAServer.

    Step 3: Wrap the PowerBuilder Component to a J2EE Component
    In Jaguar manager, an EAServer management console, you need to generate a client-side stub and server skeleton for the deployed package/component. To generate the stub/ skeleton, right-click the just deployed package, then select Generate Stub/Skeleton. On the dialog, select "Cobra" as the protocol and generate and compile Java files for stub/skeleton.

    Step 4: Create WSDL Documents and Services
    Web Services Toolkit (WST) will wrap the components to SOAP components and generate WSDL files. WST generates two WSDL files for each component - one is for the interface of the service and the other is for implementing information of the service.

    To generate WSDL files, first right-click the WSDL Documents folder and select New WSDL Document. Figure 3 shows the dialog for Create WSDL Document. Give the definition name ("helloDemo") and target namespace. The target namespace not only works as the "TargetNamespace" attribute in the WSDL file, but also specifies the location where the implementation WSDL try to look for the interface WSDL file. So it's critical for WST to generate a workable Web service. Give a URL where you want to put the interface WSDL file. Secondly, create a new Web service by right-clicking "hello Demo" document and select New Web service. You can browse all EAServer components and select any one to use. For this article, we selected package "p_hello" and component "n_ hello". Finally, add properties to the Web service. You need to specify the address for SOAP listener and which functions in the component to be exposed to Web services.

    Figure 3

    Step 5: Copy the WSDL Files For Use
    The two WSDL files generated at the last step reside under <EAServer host folder>\WebServices\work\wsdl\. Copy them to the virtual directory of the Web server. In this tutorial, we copied them to the virtual directory of http://localhost: 8090. Now the Web services are ready for use.

    Summary
    PowerBuilder 9 abstracts the complexity of the Web services development and provides a wizard-guided development environment. The sample applications in this article demonstrate the ease of Web services development. PowerBuilder 9.0 is an excellent development tool to build Web service clients both in Windows and JSP applications, and produce Web service components.

    Author Bio
    Jinyou Zhu is a senior software engineer with Sybase, Inc., and a leading developer of database and Web services for PowerBuilder 9. His expertise includes database, XML parser, Web services, and multilanguage support.

    © 2002, Sybase, Inc. All Rights Reserved

    Web Services Development with PowerBuilder 9 by Jinyou Zhu
    WSJ Vol 03 Issue 01 - pg.43

    	
    
    
    
    Listing 1: Calling Web Service from PowerScript
    
    long l_ret
    real r_rate
    
    SoapConnection conn 
    demo_currencyexchangeport p_obj 	
    
    //Create connection instance
    conn =  create SoapConnection
    
    //Set options for the connection
    conn.SetOptions("SoapLog=~"c:\\soaplog.txt~"")
    
    // Create proxy instance
    l_ret = Conn.CreateInstance(p_obj, "demo_currencyexchangeport")
    if l_ret <> 0 then
        MessageBox("Error", "Cannot create instance of proxy")
        return
    end if
    
    // Invoke Web Service
    try
        r_rate = p_obj.GetRate("us","japan")
        MessageBox("Currency Exchange Rate","1 US$ = "+ string(r_rate) + " Japanese Yens")
    catch ( SoapException e )
        MessageBox ("Error", "Cannot invoke Web Service~n" +e.getMessage())
    end try
    
    destroy conn
    
    Listing 2: TLD File for currency exchange Web Service 
    
    <?xml version="1.0" encoding="ISO-8859-1" ?> 
    <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.
    //DTD JSP Tag Library 1.1//EN"
    "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> 
    
    <taglib> 
        <tlibversion>1.0</tlibversion>
        <jspversion>1.1</jspversion>
        <shortname>CurrencyExchangeService</shortname>
    
        <tag> 
            <name>getRate</name>
            <tagclass>CurrencyExchangeService.getRate</tagclass> 
            <teiclass>CurrencyExchangeService.getRate_tei</teiclass> 
            <bodycontent>EMPTY</bodycontent> 
            <attribute>
                <name>country1</name> 
                <required>yes</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
            <attribute>
                <name>country2</name> 
                <required>yes</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
        </tag>
    </taglib>
    
    Listing 3: Calling Web Service from JSP application
    
    <%@ taglib prefix="sg" uri="WEB-INF/tlds/CurrencyExchangeService.tld" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML>
    <HEAD>
        <META HTTP-EQUIV="PowerSiteData" NAME="SERVERLANGUAGE" CONTENT="Java">
        <TITLE>DemoPage</TITLE>
        <META http-equiv="Content-Type" content="text/html; charset=windows-1252">
        <META content="PB9.0.0.5001" name="GENERATOR">
    </HEAD>
    <BODY bgColor="white" PSPARAMS="">
    <P>1US$ =  </P>
    <P><sg:getRate country1="us" country2="japan" /></P>
    <P><%= CurrencyExchangeService_getRate_returnValue %></P>
    <P>Japanese Yens  </P>
    </BODY>
    </HTML>
    
    

    All Rights Reserved
    Copyright ©  2004 SYS-CON Media, Inc.

      E-mail: [email protected]

    Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.