Welcome!

PowerBuilder Authors: Chris Pollach, Yeshim Deniz, Jayaram Krishnaswamy, Kevin Benedict, Avi Rosenthal

Related Topics: PowerBuilder

PowerBuilder: Article

Web Services with PowerJ 4.0 and PB 8.0

Web Services with PowerJ 4.0 and PB 8.0

"Web services are a new breed of Web application. They're self-contained, self-describing, modular applications that can be published, located, and invoked across the Web. Web services perform functions, which can be anything from simple requests to complicated business processes. A sample Web service might provide stock quotes or process credit-card transactions. Once a Web service is deployed, other applications (and other Web services) can discover and invoke the deployed service."
-IBM's Web Services Tutorial

The World Wide Web is mostly used as a source of information - the weather, the latest news, updates, downloading software, etc. Wouldn't it be great to go one step further and be able to request services. When I say services I don't mean a shop, I mean component services that could be used to build even bigger services.

For example, since Microsoft's Passport offers authentication services why should we build our own? We could use this service and go straight to writing our own (e.g., currency conversion), which could then be used by someone who would offer this service with his or her own (e.g., language translation or shipping information).

You might say that this can already be done since we have CORBA, RMI, Jini, and DCOM. This is true, but wouldn't it be great if everyone could write their own services and use whatever language they want to write components and clients, and anyone could access these services?

This is where SOAP comes into the picture. SOAP's implementations and tools are available in most programming languages, and in many cases for free. Developers get platform independence for Web services at little or no cost.

Introduction to SOAP
The Simple Object Access Protocol (SOAP) provides a mechanism for distributing objects over the Web. It's a way for developers to remotely make method calls upon classes and objects that exist on a remote server, without needing to know which language the objects are written in. It's the latest in a long series of similar projects like CORBA, DCOM, and XML-RPC.

SOAP defines the use of XML and HTTP to access services, objects, and servers in a platform-independent manner. It's a protocol that acts as the glue between heterogeneous software components.

Maybe you heard SOAP is a Microsoft-specific protocol. This is not true, although Microsoft offers an implementation of the specification. SOAP is supported and managed by a number of companies and has an open specification, which you can find at www.w3.org/TR/SOAP/.

We'll use Apache SOAP for our example, but you could also look at Microsoft's. Apache SOAP, an open-source implementation of SOAP v1.1 and SOAP messages with attachment specifications in Java, is developed by the Apache SOAP community.

How Does This Work?
A component installed on our application server will be our Web service that can be used by anyone. To access this service clients have to send a request. They don't know which language this service is written in and they don't care. If this request has the correct syntax, our component will be called and we'll send back a response that can be understood by everyone.

As I've already discussed, think of SOAP as a lightweight protocol for the exchange of information in a decentralized, distributed environment. It's an XML-based protocol that consists of three parts, as stated on the W3C Web site: www.w3.org/TR/SOAP/#_Toc478383494.

1. Envelope

  • The element name is "Envelope."
  • The element must be present in a SOAP message.
  • The element may contain namespace declarations as well as additional attributes. If present, such additional attributes must be namespace-qualified. Similarly, the element may contain additional subelements. If present, these elements must be namespace-qualified and follow the SOAP Body element.

    2. Header

  • The element name is "Header."
  • The element may be present in a SOAP message (not needed in our example). If present, it must be the first immediate child element of a SOAP Envelope element.
  • The element may contain a set of header entries each of which is an immediate child element of the SOAP Header element.

    3. Body

  • The element name is "Body."
  • The element must be present in a SOAP message and an immediate child element of a SOAP Envelope element. If a Header element is present, it has to follow immediately, otherwise it must be the first immediate child element of the SOAP Envelope element.
  • The element may contain a set of body entries each being an immediate child element of the SOAP Body element. Immediate child elements of the SOAP Body element may be namespace-qualified. SOAP defines the SOAP fault element, which is used to indicate error messages.

    A Request
    The HTTP Header

    In Listing 1 the URI, /soap/servlet/ rpcrouter, tells the server to route the request to the servlet sitting in EAServer. The host we're talking to is on our own machine, localhost.

    The content-type header uses a value of text/xml. SOAP defines this value to identify an HTTP entity body that contains an XML-encoded method invocation or response. All SOAP requests and responses must use this content-type value to be recognized.

    The character set may be specified, if not, the default is US-ASCII. Other acceptable character sets are UTF-8 and UTF-16. UTF-8 is recommended for maximum interoperability.

    The content length may be specified; if it is, it must be correct.

    The Envelope
    SOAP doesn't define a traditional versioning model based on major and minor version numbers. A SOAP message must have an Envelope element associated with the http://schemas.xmlsoap.org/soap/envelope/ namespace.

    The XML document stored at http:// schemas.xmlsoap.org/soap/envelope/ identifies the core elements and attributes of a SOAP message (envelope, header, and body). On receiving a document with this namespace, the receiver doesn't need to download the XML Schema. The <SOAP-ENV:Envelope.../> tag defines two additional namespaces as attributes, xmlns:xsi and xmlns:xsd, which are part of the XML namespace specification.

    The Body
    The Body element is encoded as an immediate child element of the SOAP Envelope XML element. The <SOAP-ENV:Envelope> must contain a single <SOAP-ENV:Body> element that contains a single element, the procedure call. Note that the procedure name must be a valid XML element name.

    If our procedure getmessage needs parameters, we'd have to define them now. The names of the parameters are significant; the order is not. Parameter type is indicated by the xsi:type attribute. If we add a function with parameters to the server component and call this new function by passing the two parameters, the request would contain the following:

    <al_p1 xsi:type="xsd:int">55</lowerBound>
    <al_p2 xsi:type="xsd:int">15</upperBound>

    The names of the parameters are significant; the order isn't. A procedure call may not take any parameters (as in our example), so the procedure element must not contain subelements. Table 1 provides the value types supported for parameters.

    A value can also be null, which is specified by an XML element with an attribute, xsi:null, whose value is 1: <p1 xsi:null="1"/>.

    Note that the SOAP protocol doesn't specify or imply the method for processing. The supplier could run a CGI script, invoke a servlet or a PB component, or perform any other process that would produce the appropriate response to the request. The response would be in the form of an XML document in which the results are placed in an element whose name matches the method name suffixed by "Response."

    The Response
    Let's take a closer look at what we get back from our component call. If we call the component the same way we call a standard PB component, we'd get back our "Hello World" String, but with SOAP it's a little different (see Listing 2).

    The HTTP Header
    Unless there's an error, return 200 OK. The content type is text/xml. Content length may be specified; if it is, it must be correct.

    The Envelope
    The body of the response is (of course) in XML, a single <SOAP-ENV:Envelope> element. The <SOAP-ENV:Envelope> must again contain a single <SOAP-ENV:Body> element that contains a single element, which is the returned value of the procedure.

    The Body
    The single element contained in the <SOAP-ENV:Body> has an arbitrary name that must match the name of the called procedure, with "Response" tacked on to the end of its name. Let's call this element the wrapper for the response. Even this isn't the actual value of the response, which is contained in the single optional subelement of the wrapper and must be a valid parameter. The namespace of the wrapper element should match the namespace in the request. If the wrapper doesn't have any subelements, the procedure didn't return a value.

    Let's Do It with Our Tools
    Install SOAP

    Download Apache SOAP from http://xml.apache.org/dist/soap/version-2.2/soap-bin-2.2.zip. Unzip soap-bin-2.2.zip to C:\soap.

    Jason Weiss wrote a good article that explains this step-by-step: "Installing Apache SOAP 2.2 with Sybase EAServer 3.6.1 and 4.0," http://my.sybase.com/detail?id=1013352.

    The Server Component
    Create a directory where we'll store our PowerBuilder and PowerJ Workspace (C:\soap).

    In PowerBuilder, create a new Workspace called soap (File -> New -> Workspace) in your new directory and start EAServer 4. Create a new EAServer component (File -> New -> Target) (see Figure 1).

    Follow the wizard and enter in the following information, accepting the default where nothing is specified:

    • Application name: Soapapp
    • EAServer component name: Soapapp
    • Package name: Soap
    • Specify transaction support: Check auto demarcation/deactivation
    • Project: p_deploy
    Open n_soapapp and create a function (getmessage returns String) in which you return Hello World (see Figure 2).

    Open p_deploy and deploy your component. Now open Jaguar Manager and connect using jagadmin and an empty password. Go to your SOAP package where you can see your component and edit the property (see Figures 3 and 4).

    com.sybase.jaguar.component.home = soap::soapappHome

    Generate EJB stubs and skeletons (RMB on soapapp):

    • Generate stubs: Checked
    • Generate Java stubs: Checked
    • Generate Java files: Check radio button
    • Compile Java stubs: Checked
    • Generate skeletons: Checked
    A SOAP Client
    In PowerJ, create a new workspace called soap (File -> New Workspace) in C:\soap. Create a new Java classes target (File -> New... from within Workspace View). Follow the wizard and enter in the following information, accepting the default if nothing is specified:

  • Target name: soapClasses

    Create a new standard class (RMB logonClasses Target -> New... from within Workspace View).

    Follow the wizard and enter in the following information, accepting the default if nothing is specified:

  • Class Name: PBClient

    Add C:\soap-2_2\lib\soap.jar to the Build Options ClassPath or to your global ClassPath (see Figure 5).

    Now change the source code for PBClient.java (see Listing 3).

    Configure SOAP
    We tell SOAP that we have an EJB (we generated EJB stubs and skeletons, right?) sitting on EAServer waiting for our clients. Let's create an XML file (see Listing 4).

    We use this file to deploy to SOAP. We have to create a batch file that will do this for us (see Listing 5).

    This file could be used to deploy any correct DeploymentDescriptor.xml to SOAP. It simply takes the file and calls the SOAP servlet that's sitting in your EAServer (localhost:8080). So let's deploy....

    You'll see that urn:testprovider was just deployed to SOAP (see Figure 6). The other SOAP service, urn:string-service, may be shown next time.

    Test the Web Service
    I wrote the files DeploymentDescriptor.xml, deploy.cmd, and run.bat outside PowerJ and imported them to the soapClasses target.

    If you created everything, your workspace should look like mine (see Figure 7). Tip: Enable Show All Files on the soapClasses target to see the JAR file.

    Apache SOAP includes an application in which you can view the request to SOAP and the answer to the client. Start it in a DOS box with the command:

    java org.apache.soap.util.net.TcpTunnelGui 8090 localhost 8080

    You should have C:\soap-2_2\lib\soap.jar in your ClassPath.

    To test your Web service use the batch file provided in Listing 6. You'll be able to see the request and the response in the TcpTunnelGui and your DOS box should look like Figures 8 and 9.

    Problem Solving
    If you have problems with the XML parsers look for the file %SYBASE%\Shared\Sun\ jdk122\jre\lib\ext\jaxp.jar and remove it, if it exists.

    If you have any problems deploying the PB component to EAServer, visit the Sybase newsgroups. This is a great source with lots of helpful people.

    If your run.bat file fails because it can't find the EJB, try to restart EAServer. Refreshing the package doesn't help after creating the Home interface by EAServer.

    The only problem I had was with the wrong version of the crimson.jar file:

    File name   Size
    crimson.jar   187.162
    soap.jar   220.703
    xalan.jar   801.714

    Conclusion
    SOAP is a Remote Procedure Calling protocol that works over HTTP. The body of the request is in XML. A procedure executes on the server and the value it returns is also formatted in XML. Procedure parameters and returned values can be scalars, numbers, strings, dates, etc., and can also be complex record and list structures.

    Resources

  • More Stories By Berndt Hamboeck

    Berndt Hamboeck is a senior consultant for BHITCON (www.bhitcon.net). He's a CSI, SCAPC8, EASAC, SCJP2, and started his Sybase development using PB5. You can reach him under [email protected]

    Comments (0)

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.