Client Application Developer's Guide

     Previous  Next    Open TOC in new window    View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

Enabling DSP Applications for Web Service Clients

Web services provide an industry-standard way to develop SOA (service-oriented architecture) applications. Such services can be thought of as loosely coupled, distributed units of programming logic that can be re-configured easily to deliver new application functionality, both intra- and extra-enterprise.

Using Web services and BEA AquaLogic Data Services Platform (DSP) allow your applications to better leverage enterprise data assets.

This chapter explains you how to expose data services as standard Web services, and how to create client applications that can obtain the benefits of both Web services and SDOs. It covers these topics:

For more information about Web services, see:

http://download.oracle.com/docs/cd/E13222_01/wls/docs81/webservices.html

 


Overview of Web Services and DSP

Exposing data services as Web services makes your information assets accessible to a wide variety of client types, including other Java Web service clients, Microsoft ADO.NET and other non-Java applications, and other Web services. Figure 4-1 illustrates the various approaches that client application developers can take to integrating data services and Web services.

Figure 4-1 Web Services Enables Access to DSP-Enabled Applications from a Variety of Clients

Web Services Enables Access to DSP-Enabled Applications from a Variety of Clients

Note: For information about ADO.NET-enabled Web services and client applications, see Supporting ADO.NET Clients.

Different Styles of Web Services Integration for DSP

Data services can be integrated with Web services in one of two general ways:

Figure 4-2 shows the end-to-end process — both the server-side and client-side tasks — that expose a DSP-enabled application as a Web service and implement a client application that invokes operations on that service.

Figure 4-2 Java Clients Supported via Web Services

Java Clients Supported via Web Services

 


Server-Side DSP-Enabled Web Service Development

DSP-enabled Web service development depends on whether you are working with read-only Web services or Web services which support read-write functionality.

Developing DSP-Enabled Read-Only Web Services

There are two ways to create Web services from data services. By:

Both approaches rely on Data Service controls as the component-based integration mechanism.

Adding a Data Service Control to a Web Service

You can easily add one or more Data Service controls to a Web service using WebLogic Workshop. Firstcreate a folder for the controls inside the Web service's project folder, and then create the Data Service controls.

You can also create controls during the process of adding them to the Web service but, for simplicity's sake, the instructions in this section assume that you have created the Data Service controls in advance. (See Creating Data Service Controls for more information on creating Data Service controls.)

Here are the steps involved:

  1. In WebLogic Workshop, open an existing Web service file (JWS) by double-clicking on its name in the Application pane.
  2. Click the Design View tab on the Web service to open the graphical representation of the Web service (as shown in Figure 4-3).
  3. Figure 4-3 Adding a Data Service Control to a Web Service


    Adding a Data Service Control to a Web Service

  4. Right-click and select Add Control Æ Data Service from the popup menu. The Insert Control - Data Service wizard launches (Figure 4-4).
  5. In the STEP 1 field of the dialog, enter a variable name for the Data Service control which is unique in the context of the Web service.
  6. Figure 4-4 Insert Control - Data Services Wizard


    Insert Control - Data Services Wizard

  7. In the STEP 2 field, click Browse... to navigate to the controls folder, then select the Data Service control you want to add to the Web service. (Alternatively, click Create a New Data Service Control button to launch the Data Service control wizard to create and configure a new control.)
  8. Leave the checkbox labeled Make This a Control Factory unselected. (This checkbox would cause the Data Service control to be instantiated at runtime using the factory pattern, rather than as a singleton. To use the control in a Web service, it must be a singleton.)

  9. STEP 3 is active only if your Data Service control is associated with a remote DSP instance; that is, a DSP instance running on a separate domain from WebLogic Workshop. The dialog provides for entry of a user name, password, server URL, and domain information associated with the remote Data Service control. This information is needed to complete the link between the Web service and the control.
  10. Click the Create button on the Insert Control - Data Service dialog. The LiquidDataControl.jar file is copied into the Libraries directory of the application. The variable you created in STEP 1 of the dialog displays as a node in the Data Palette, with its functions and procedures listed under the node.
  11. It is these functions and procedures that you can now expose to client applications, by adding them to the Web service's callable interface (shown as the left-hand portion of the Web service's Design View in WebLogic Workshop — see Figure 4-5), as described in the next step.

    Figure 4-5 Adding Data Service Control Functions to a Web Service


    Adding Data Service Control Functions to a Web Service

  12. Select the variable's function or procedure listed in the Data Palette by clicking on the node, and then dragging the function onto the left side of the Web service in Design View.

You can test your Web service as described in Testing a Web Service in WebLogic Workshop. After testing, you can deploy your Web service to a production WebLogic Server and use it as you would any other Web service. For information about developing Java-based Web service clients, see Client-Side DSP-Enabled Web Service Development.

Generating a Web Service from a Data Service Control

Another way to create a DSP-enabled Web service is by generating stateless Web services from Data Service controls. The generated Web services automatically include operations (method calls) for each of the functions and procedures that the Data Service control comprises.

Follow the instructions in this section to generate and test a stateless Web service. (These instructions assume that you have already created the Data Service control and that WebLogic Workshop is open.)

Figure 4-6 Stateless Web Services Are Generated from Data Service Controls

Stateless Web Services Are Generated from Data Service Controls

Here are the steps involved:

  1. From WebLogic Workshop's Application pane, select the Data Service control that you want to use as the basis for your Web service by clicking on its name. While the control is selected, right-mouse-click to display the pop-up menu; select Generate Test JWS File (Stateless) from the menu. WebLogic Workshop generates the JWS Java Web service file for your Data Service control.
  2. Note: Although WebLogic Workshop by default generates Web services that have the word "Test" embedded in the file names, these are deployable Web services. You can rename the generated Web service to eliminate the word "Test".
  3. Click on your Web service project to select it, then right-click, and select Build Project. WebLogic Workshop builds a Web service project.
  4. When the build process completes, double-click on the JWS file. If necessary, click the Design View tab to display the generated Web service in the Design View.
  5. You will see methods (operations) for each of the functions and procedures contained in the Data Service control.

Developing DSP-Enabled Read-Write Web Services

If your Web service must support submits from Java Web service clients, you first need to modify the JWS file before generating the WSDL, as follows:

  1. Modify submit operations in your Java Web service (JWS) implementation control file to accept a DatagraphDocument object as a parameter.
  2. For instance, if the original signature of the submit() method of the generated JWS looks appears as:

    java.util.Properties[] submitCustomerProfile(CustomerProfileDocument doc);

    It should be modified to the following:

    java.util.Properties[] submitCustomerProfile(DatagraphDocument rootDataObject)
  3. Modify the body of the submit operation to instantiate and initialize the document from a DatagraphDocument object being passed as a parameter; for example:
  4. CustomerProfileDocument doc = (CustomerProfileDocument) new    DataGraphImpl(rootDataObject).getRootObject();
    return customerData.submitCustomerProfile(doc); //customerData is the DSP control
  5. Generate a Web Service Definition Language (WSDL) file from the JWS file by right-clicking on the file name and selecting the Generate WSDL file option.

After you have created the WSDL file, provide it to your client application developers, so they can generate the Web services client interfaces and proxy code necessary (as discussed in Client-Side DSP-Enabled Web Service Development).

Testing a Web Service in WebLogic Workshop

By default, WebLogic Workshop creates two operations in its generated Web services that can be used for testing purposes.

  1. Click the Start icon (or select Debug Arrow symbol Start from the WebLogic Workshop menu) to deploy and run the Web service using the local runtime. An informational message briefly appears, notifying you that the Web service is running. Shortly, the WebLogic Workshop Test Browser launches, displaying the Test Form.
  2. Click the Test button to run the Web service and obtain your result.

Continue developing the functionality of the Web service as required, testing as you go along. Once the Web service is complete, you can create the artifacts necessary for client application development, as described in the next section, Client-Side DSP-Enabled Web Service Development.

Note: For more information about Web service client applications and WebLogic Server in general, see Invoking Web Services in Programming WebLogic Web Services in WebLogic Server documentation.

 


Client-Side DSP-Enabled Web Service Development

Your client application uses either a static or a dynamic approach to Web services. Both approaches are discussed in this section. The following topics provide brief summaries of the appropriate uses of static and dynamic clients.

Static Web Service Clients

A static Web service client requires:

DSP includes the necessary utilities (Java classes and Ant tasks) to generate the following classes for your static Web service client:

Dynamic Web Service Clients

A dynamic Web service client requires:

Neither the generated SDO classes, nor the Web service client proxy classes are needed for the Dynamic Web service client.

A typical dynamic Web service client can retrieve a customer's record with the following:

XmlObject param = XmlObject.Factory.parse( "<msg:getCustomer xmlns:msg='http://www.openuri.org/'><CustomerID>987654</CustomerID></msg:getCustomer>");
DataObject doc = (DataObject)call.invoke(new Object[]{param});
Note: The call class is an instance of the Call interface of the JAX-RPC API. The doc object is an instance of the DataObject interface of the Dynamic SDO API.

Developing Static Web Service Clients

The following general steps are involved in developing a static Web service client for DSP:

Generating the DSP Web Service Proxy

You can generate an SDO Web service client using an Ant task (SDO Web Service Client Gen) or through a Java class (WSClientGen). Each approach is described in this section.

Generating SDO Classes Using Ant

The SDOGen Ant task creates an SDO client JAR file that contains the typed classes for working with SDOs. It can use either the XSD files from the data service or the WSDL (assuming the DSP-enabled application has been exposed as a Web service) to generate the SDO classes and compile them into the client JAR file.

The SDOGen Ant task lets you build the necessary SDO client JAR which you can then use in your client application code.

Environmental Settings

To generate the necessary classes, make sure your classpath includes:

Syntax

To create a JAR comprising the client classes, execute sdogen at the command prompt as follows:

  1. Add the sdogen taskdef to the build script. For example:
  2. <taskdef name="sdogen" classname="com.bea.sdo.impl.SDOGenTask" classpath="path/to/wlsdo.jar:path/to/xbean.jar"/> 

    where path/to is replaced with the location of your JAR files.

    This task implicitly defines an Ant FileSet, and supports all FileSet attributes (for example, dir becomes basedir) as well as the nested attributes and elements. Table 4-7 summarizes the attributes used by the sdogen Ant task.

    Table 4-7 Attributes Available for DSP's SDO Generation (sdogen) Ant Task
    Attribute
    Description
    Required?
    Default Value
    schema
    A file that points to either an individual schema file or a directory of files. Not a path reference. If multiple schema files need to be built together, use a nested fileset instead of setting schema.
    Yes
    None
    destfile
    Creates a non-default name for the JAR file. For instance, myXMLBean.jar will output the results of this task into a JAR named myXMLBean.
    No
    xmltypes.jar
    classgendir
    Directory in which to generate .class files.
    No
    Current directory
    classpath
    Specify the classpath if Java files are in the schema fileset, or if the fileset imports include compiled XMLBeans JAR files. Also supports a nested classpath.
    No
     
    classpathref
    Adds a classpath, given as reference to a path defined elsewhere.
    No
     
    debug
    Indicates whether source should be compiled with debug information.
    If set to False (off), -g:none will be passed on the command line for compilers that support it.
    If set to True, the value of the debuglevel attribute determines the command line argument.
    No
    False (off)
    fork
    Flag that indicates whether the JDK compiler (javac) should be executed externally.
    No
    Yes
    memoryInitialSize
    The initial size of the memory for the underlying VM, if javac is run externally; ignored otherwise. Defaults to the standard VM memory setting.
    No
    Configured VM memory setting for the machine. For example: 83886080, 81920k, or 80m.
    memoryMaximumSize
    The maximum size of the memory for the underlying VM, if javac is run externally; ignored otherwise. Defaults to the standard VM memory setting.
    No
    Configured VM memory setting for the machine. For example: 83886080, 81920k, or 80m.
    verbose
    Controls the amount of build message output.
    No
    True

To build a WSDL or XML schema definition (XSD) files in the schemas directory and create a JAR named Schemas.jar, your Ant script would need to include the following:

<sdogen schema="MyTestWS.WSDL" destfile="Schemas.jar" 
classpath="path/to/wlsdo.jar:path/to/xbean.jar"/> 

where path/to represents the actual location of your JAR files.

Generating SDO Classes Using Java

Rather than using the SDOGen Ant task, you can use the SDOGen Java class at the command-line to generate SDO client classes from XML schema definition (XSD) files or WSDL files based on data services.

SDOGen is a Java class that extends the XMLBean schema compiler class. See Table 4-8 for other command-line options for the SDOGen utility.

Table 4-8 Command-line Options for the Java SDO Class Generation Utility
Option
Description
Default Value
-cp [a;b;c]
Classpath.
 
-d [dir]
Target directory for binary .class and .xsb files.
 
-src [dir]
Target directory for generated Java source files.
 
-srconly
Flag to prevent compiling Java source files and archiving into JAR file.
 
-out [result.jar]
Name of the output JAR file.
xmltype.jar
-dl
Enables network downloads for imports and includes.
Off (not enabled).
-noupa
Do not enforce the unique particle attribution rule.
 
-nopvr
Do not enforce the particle valid (restriction) rule.
 
-compiler
Path to external Java compiler.
 
-jar
Path to JAR (Java Archive) utility.
 
-ms
Initial memory for external Java compiler.
8 Megabyte
-mx
Maximum memory for external Java compiler.
256 Megabyte
-debug
Compile with debug symbols.
 
-quiet
Print minimal informational messages to Java console.
 
-verbose
Print maximum amount of informational messages to Java console.
 
-license
Prints license information.
 
-allowmdef "[ns] [ns] [ns]"
Ignores multiple defs in given namespaces.
 

Environmental Settings

To execute the utility, make sure your classpath includes:

Syntax

To create a JAR comprising the client classes, execute SDOGen at the command prompt as follows:

java com.bea.sdo.impl.SDOGen [options] xmlschema

The XMLSchema can be:

SDOGen Usage Examples

Here are some examples showing use of the SDOGen Web service client generation utility:

The following are examples of using SDOGen with various options (Table 4-8) to obtain different results:

How To Set Up a Web Service Client Environment for DSP

The following instructions enable you to set up your Web service client environment for DSP.

After generating the SDO Web service client classes in a JAR file (SDOClient.jar), set up the classpath for the Web service client using the following JAR files in the following order:

Steps Involved in Developing Your Web Service Client

If you are not already familiar with the concept of using a Web service client proxy or JAX-RPC API to invoke Web services, see the following document:

Then, in developing your Web service client, follow these steps:

  1. Invoke the Web service method (e.g. getCustomer) to get the strongly typed root SDO data object (e.g. CUSTOMERDocument). At this point, a SDO datagraph has already been created and attached to the root data object (i.e. CUSTOMERDocument). Change tracking is also turned on by default.
  2. Use the Static SDO API to read the data (e.g. getCustomerName). Alternative you can use the static API to modify the data (e.g. setCustomerName("J D")).
  3. Alternatively, you can also use the dynamic SDO API to read or modify the data.

    See DSP's Data Programming Model and Update Framework for details on handling insertions and deletions using the static and dynamic SDO APIs.

  4. Invoke the Web service proxy method to submit the changed SDO datagraph to your server to update your data sources. Here is an example of such an invocation:
  5. wssoap.submitCustomer(((DataGraphImpl)doc.getDataGraph()).getSerializedDocument());

Sample Java Static Web Service Client

The following code shows a sample Java static Web services client for DSP:

public class ClientTest {
public static void main(String[] args) throws Exception {
SimpleCtrlTest wstest = new SimpleCtrlTest_Impl();
SimpleCtrlTestSoap wssoap = wstest.getSimpleCtrlTestSoap();
CUSTOMERDocument doc = wssoap.getCustomer(987654);

doc.getCUSTOMER().setCUSTOMERNAME("J D");

wssoap.submitCustomer(((DataGraphImpl)doc.getDataGraph()).getSerializedDocument());
}

Developing Dynamic Web Service Clients

Developing your dynamic Web services involves the following:

Setting Up a Dynamic Web Service Environment

Set up the classpath for your Web service client using the following JAR files in the following order:

Note: The order of files shown above must be maintained.

Developing the Dynamic Web Service Client

There are three aspects to developing a dynamic Web service client. First the client must be created using standard development procedures. Then there are several DSP-specific steps.

Initiating Dynamic Web Service Client Development

Follow the JAX-RPC instructions in JAX-RPC documentation ( http://java.sun.com/webservices/jaxrpc/docs.html) to create the framework for a dynamic Web services client. Essentially this work involves:

Steps Specific to DSP

To enable the dynamic Web service for Data Services Platform you then need to:

  1. Create a DataGraphCodec instance using the URL to WSDL.
  2. Create a TypeMappingRegistry.
  3. Create a TypeMapping and register the DataGraphCodec instance to be used to serialize/de-serialize the SOAPElement for both the request and response message.
Completing Dynamic Web Service Client Development

Finally complete development by:

  1. Creating an instance of the JAX-RPC call interface for your read method (such as getCustomer( ) ).
  2. Invoke your Web service.
  3. Read or modify the response data using the SDO Dynamic Data API.
  4. Create a call instance for the submit( ) method (such as submitArrayOfCustomer( ) ).
  5. Wrap the serialized SDO datagraph with the SOAP message for the submit( ) method.
  6. Invoke the submit( ) method to update your data sources.

Sample Java Dynamic Web Service Client

The following code (with comments emphasized) shows a complete Java dynamic Web services client for DSP, including import statements.

Listing 4-1 Sample Java Dynamic Web Service Client
import com.bea.sdo.impl.DataGraphCodec;
import com.bea.xml.XmlObject;
import commonj.sdo.DataObject;
import java.io.File;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.encoding.TypeMapping;
import javax.xml.rpc.encoding.TypeMappingRegistry;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPElement;

public class TestCodecArray
{
public static void main(String args[]) throws Exception {

System.setProperty("javax.xml.soap.MessageFactory", "weblogic.webservice.core.soap.MessageFactoryImpl");

// Setup the global JAX-RPC service factory
System.setProperty( "javax.xml.rpc.ServiceFactory", "weblogic.webservice.core.rpc.ServiceFactoryImpl");

// create service factory
ServiceFactory factory = ServiceFactory.newInstance();

// define qnames
String targetNamespace = "http://www.openuri.org/";

QName serviceName = new QName(targetNamespace, "org3Test");

QName portName = new QName(targetNamespace, "org3TestSoap");

URL wsdlLocation = new URL("http://localhost:7001/ElecWS/controls/org3Test.jws?WSDL");

// create service
Service service = factory.createService(wsdlLocation, serviceName);

// create Codec
DataGraphCodec dgCodec = new DataGraphCodec(wsdlLocation);

TypeMappingRegistry registry = service.getTypeMappingRegistry();

TypeMapping mapping = registry.getTypeMapping( SOAPConstants.URI_NS_SOAP_ENCODING );

mapping.register( SOAPElement.class,
new QName(targetNamespace, "getCustomer"),
dgCodec,
dgCodec );
mapping.register( SOAPElement.class,
new QName( targetNamespace, "getCustomerResponse" ),
dgCodec,
dgCodec );
mapping.register( SOAPElement.class,
new QName( targetNamespace, "submitArrayOfCustomer" ),
dgCodec,
dgCodec );
mapping.register( SOAPElement.class,
new QName( targetNamespace, "submitArrayOfCustomerResponse" ),
dgCodec,
dgCodec );

// create call for read
Call call = service.createCall(portName, new QName(targetNamespace, "getCustomer"));

XmlObject reqdoc = XmlObject.Factory.parse( "<getCustomer xmlns='http://www.openuri.org/'/>");

DataObject[] customerdocs = (DataObject[]) call.invoke(new Object[]{reqdoc});


// user can modify the DataObject here
DataObject customer = customerdocs[0].getDataObject(0);
customer.setString("EmailAddress", "BEAarray@BEA.com");

String dgstring = customer.getDataGraph().toString();
System.out.println(dgstring);

// create call for submit
call = service.createCall(portName, new QName(targetNamespace, "submitArrayOfCustomer"));

XmlObject submitdoc = XmlObject.Factory.parse( "<sub:submitArrayOfCustomer xmlns:sub='http://www.openuri.org/'><sub:docs>" +    dgstring +
"</sub:docs></sub:submitArrayOfCustomer>");

Object obj = call.invoke(new Object[]{submitdoc});

System.out.println(obj);

}
}

  Back to Top       Previous  Next