Book Image

SoapUI Cookbook

By : Rupert Anderson
Book Image

SoapUI Cookbook

By: Rupert Anderson

Overview of this book

Table of Contents (19 chapters)
SoapUI Cookbook
Credits
About the Author
Acknowledgments
About the Reviewers
www.PacktPub.com
Preface
Index

Generating a WSDL-first web service using SoapUI tool integration


This recipe shows how to configure SoapUI (Apache CXF) tool integration to generate a runnable Java web service with an empty implementation using its WSDL. This could be useful if you need a quick menu-driven way to create a SOAP web service that can be implemented and deployed separately to SoapUI.

Getting ready

The WSDL that we are going to use defines a simple invoice service. It has only one operation to retrieve a basic invoice document using its invoice number:

  • Operation: getInvoice

  • Request: invoiceNo : string

  • Response: InvoiceDocument (invoiceNo : string, company : string, amount : string)

  • Location: http://localhost:9001/ws/invoice/v1

The WSDL can be found at soap/invoicev1/wsdl/invoice_v1.wsdl in this chapter's sample code.

We'll need the Apache CXF web service framework to generate the web service stub using SoapUI tooling. Download the latest version from http://cxf.apache.org/download.html (I have used version 3.01).

Tip

Apache CXF Version

Despite the tool menu stating version 2.x, you can go for the latest version, which, at the time of writing, is 3.01 (requires JDK 1.7+). Otherwise, choose version 2.7.x for JDK 1.6+ support, or version 2.6.x for JDK 1.5 support.

To build and run the service Java code, the minimum you will need is a suitable JDK. I have used JDK 1.7.0_25. Optionally, you may also want to use an IDE like Eclipse to make easy the work of exploring, building, and running the generated web service code.

Tip

Other SoapUI Tools

While you are free to choose any alternate framework supported by SoapUI tools (see http://www.soapui.org/SOAP-and-WSDL/code-generation.html), note that although the principles will stay the same, the command details and the resulting generated web service artifacts will of course vary.

How to do it...

First, we need to configure SoapUI to be able to generate and build the invoice web service. Then, we can run it as a standard Java executable. Perform the following steps:

  1. In SoapUI, go to Tools | Apache CXF, and when the Apache CXF Stubs window appears, click on the Tools button to bring up the SoapUI Preferences window. Here, browse to the location where you downloaded Apache CXF, select the bin directory, and then click on OK:

  2. Next, we need to configure the generation options under the Basic tab. The main points are:

    • WSDL location: For example, <chapter1 samples>/soap/invoicev1/wsdl/invoice_v1.wsdl.

    • Output directory: This is where the generated source code will end up; for example; <chapter1 samples>/soap/invoicev1/src/main/java.

    • Package Structure: This is for the generated source code; for example, ws.invoice.v1.

    • Artifact Options: Only tick Server and Implementation. However, the client and Ant build file options are also available. We will be using SoapUI as our client and won't require Ant.

  3. To automatically compile our generated service code, under the Advanced tab, do the following:

    • Tick Compile.

    • Supply a Class Folder value for the resulting Java class files, for example, <chapter1 samples>/soap/invoicev1/target/classes.

    • Tick Validate WSDL (optional) under the advanced tab to check the structure and get basic WS-I compliance checks on your WSDL. Note that the invoice_v1.wsdl should not produce any output with this option.

    • Leave all other fields and checkboxes unchanged.

  4. Under the Custom Args tab, enter –wsdlLocation invoice_v1.wsdl in Tool Args. This tells the web service code where to look for the WSDL file at runtime. Setting the value like this means that invoice_v1.wsdl is expected to be the root of the classes directory. More on this in the next section.

  5. Now, we are ready to click on Generate! If all goes well, you should see an output similar to the following:

    You should also see the following generated Java source files in your output folder, for example:

    <chapter1 samples>/soap/invoicev1/src/main/java/ws/invoice/v1/
    
    InvoiceDocumentType.java
    InvoicePortType_InvoicePort_Server.java 
    ObjectFactory.java InvoicePortImpl.java 
    InvoiceRefType.java package-info.java 
    InvoicePortType.java InvoiceServiceV1.java

    The corresponding class files in your class folder, for example:

    <chapter1 samples>/soap/invoicev1/target/classes/ws/invoice/v1/

    Note

    Mac/Linux Issue

    I suspect that there is a minor SoapUI bug here. If you get an error like sh: ./wsdl2java.sh: No such file or directory, then an easy fix is to open a shell in <Apache CXF Home>/bin/ and copy wsdl2java to wsdl2java.sh; for example, cp wsdl2java wsdl2java.sh.

  6. Before we run the server, we need to copy invoice_v1.wsdl into the classes folder location, for example, into <chapter1 samples>/soap/invoicev1/target/classes. Otherwise, when the server is run, you will see an error like [failed to localize] cannot.load.wsdl(invoice_v1.wsdl).

  7. Finally, we are ready to start the server:

    cd <chapter1 samples>/soap/invoicev1/target/classes
    java ws.invoice.v1.InvoicePortType_InvoicePort_Server
    Starting Server
    Server ready...
    

To confirm whether it's actually working, open a browser and go to http://localhost:9001/ws/invoice/v1?wsdl, and you should see the (invoice_v1.wsdl) WSDL displayed. Our generated server is up and running.

How it works...

All that SoapUI is actually doing is building command-line parameters for the various web service frameworks to do the generation. In this example, those happy with the command line could just run <Apache CXF Home>/bin/wsdl2java directly.

Note

Apache CXF wsdl2java script

For more info on the wsdl2java options, see http://cxf.apache.org/docs/wsdl-to-java.html.

Let's take a quick look at the generated source files. The main points are as follows:

  • Running the wsdl2java option generates Java standard JAX-WS web service code with types and methods derived from the WSDL.

  • The Java JDK ships with an implementation of JAX-WS:

    • There's no need for any additional compile or runtime libraries, for example, Apache CXF libs.

    • No servlet container is required to publish the web service, for example, Tomcat or Jetty. If you look in InvoicePortType_InvoicePort_Server.java, you can see that the service is published using JDK's default HTTP server provided by the javax.xml.ws.Endpoint class. The static Endpoint.publish(…) binds our generated service implementation (InvoicePortImpl.java) to the endpoint address so that invoice requests are handled by our getInvoice(…) method.

  • The service is very portable; that is, only a Java JRE is needed to run it.

  • The WSDL file is required at runtime. The wsdlLocation parameter supplied in step 4 sets an attribute of the @javax.jws.WebService annotation in the class InvoicePortImpl.java.

  • The server endpoint and timeout (the default value is 5 minutes) are easy to change. Edit InvoicePortType_InvoicePort_Server.java:

    • Endpoint: String address = "http://localhost:9001/ws/invoice/v1";

    • Timeout: Thread.sleep(5 * 60 * 1000);

    • Requires recompile

There's more...

If the generated web service stub is to be used as the basis for on-going service development, then managing the generation, build, and deploy cycle externally to SoapUI using a build framework such as Ant, Maven, or Gradle will probably be a better option. To help with this, Apache CXF has a good Maven plugin to provide similar code generation; refer to http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html.

For those who want a quick and high-level way to generate a working web service for testing purposes, I would expect SoapUI's excellent mocking features to be a more convenient option than code generation in many cases (See Chapter 3, Developing and Deploying Dynamic REST and SOAP Mocks).

The SOAP web service stub journey will be continued in the next recipe when we add simple SoapUI tests and a basic implementation to pass them.

See also