+

Search Tips   |   Advanced Search

Example: Creating a Web service that uses the IBM proprietary Web Services Addressing API to access a generic Web service resource instance


Consider an IT organization that has a network of printers that it wants to manage using Web services. The organization might represent each printer as a resource that is addressed through an endpoint reference. This example shows how to code such a service using the IBM proprietary Web Services Addressing (WS-Addressing) APIs that are provided by WAS, and JAX-WS.

 

Providing a Web service interface that returns an endpoint reference to the target service

The IT organization implements a PrinterFactory service that offers a CreatePrinter portType element. This portType element accepts a CreatePrinterRequest message to create a resource that represents a logical printer, and responds with an endpoint reference that is a reference to the resource. The WSDL definition for such a PrinterFactory service might include the following code:

<wsdl:definitions targetNamespace="http://example.org/printer" ...
                  
    xmlns:pr=" http://example.org/printer">
  <wsdl:types>
    ...
    <xsd:schema...>
      <xsd:element name="CreatePrinterRequest"/>
      <xsd:element name="CreatePrinterResponse" 
                   type="wsa:EndpointReferenceType"/>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="CreatePrinterRequest">
    <wsdl:part name="CreatePrinterRequest" 
               element="pr:CreatePrinterRequest" />
  </wsdl:message>
  <wsdl:message name="CreatePrinterResponse">
    <wsdl:part name="CreatePrinterResponse" 
               element="pr:CreatePrinterResponse" />
  </wsdl:message>
  <wsdl:portType name="CreatePrinter">
    <wsdl:operation name="createPrinter">
      <wsdl:input name="CreatePrinterRequest" 
                  message="pr:CreatePrinterRequest" />
      <wsdl:output name="CreatePrinterResponse"
                  message="pr:CreatePrinterResponse" />
    </wsdl:operation>
  </wsdl:portType>
</wsdl:definitions>

The CreatePrinter operation in the previous example returns a wsa:EndpointReference object that represents the newly created Printer resource. The client can use this endpoint reference to send messages to the service instance that represents the printer.

 

Implementing the Web service interface

The createPrinter method shown in the following example creates an endpoint reference to the Printer service. The operation then obtains the identifier for the individual printer resource instance, and associates it with the endpoint reference. Finally, the createPrinter method converts the EndpointReference object, which now represents the new printer, into a W3CEndpointReference object, and returns the converted endpoint reference.

import com.ibm.websphere.wsaddressing.EndpointReferenceManager;
 import com.ibm.websphere.wsaddressing.EndpointReference;
 import com.ibm.websphere.wsaddressing.jaxws.EndpointReferenceConverter;
 import com.ibm.websphere.wsaddressing.jaxws.W3CEndpointReference;
 import javax.xml.namespace.QName;
 public class MyClass {

    
// Create the printer
    ...

    
// Define the printer resource ID as a static constant as it is required in later steps
    public static final QName PRINTER_ID_PARAM_QNAME = new QName("example.printersample",                                                                  "IBM_WSRF_PRINTERID", "ws-rf-pr" ); 
    public static final QName PRINTER_SERVICE_QNAME = new QName("example.printer.com", "printer", "..."); 
    public static final String PRINTER_ENDPOINT_NAME = new String("PrinterService");
    
    public W3CEndpointReference createPrinter(java.lang.Object createPrinterRequest)
    throws Exception {
     
// Create an EndpointReference that targets the appropriate WebService URI and port name.
     EndpointReference epr =  EndpointReferenceManager.createEndpointReference(PRINTER_SERVICE_QNAME, 
                                                                               PRINTER_ENDPOINT_NAME);

     
// Create or lookup the stateful resource and derive a resource
     
// identifier string.
     String resource_identifier = "...";

     
// Associate this resource identifier with the EndpointReference as  
     
// a reference parameter.
     
// The choice of name is arbitrary, but should be unique     
     
// to the service.
     epr.setReferenceParameter(PRINTER_ID_PARAM_QNAME,resource_identifier);
     
// The endpoint reference now targets the resource rather than the service.
     ...

     return EndpointReferenceConverter.createW3CEndpointReference(epr);
    }
}

 

Extending the target service to match incoming messages to Web service resource instances

Because of the Web service implementation described previously, the printer resource instance now has a unique identifier embedded in its endpoint reference. This identifier becomes a reference parameter in the SOAP header of subsequent messages that are targeted at the Web service, and can be used by the Web service to match incoming messages to the appropriate printer.

When a Web service receives a message containing WS-Addressing message-addressing properties, the WAS processes these properties before the message is dispatched to the application endpoint, and sets them into the message context on the thread. The Printer Web service application accesses the reference parameters that are associated with the target endpoint from the WebServiceContext object, as illustrated in the following example:

import com.ibm.websphere.wsaddressing.EndpointReferenceManager; 
...
 
// Initialize the reference parameter name

QName name = new QName(..); // Extract the String value.

String resource_identifier = EndpointReferenceManager.getReferenceParameterFromMessageContext(PRINTER_ID_PARAM_QNAME);

The Web service implementation can forward messages based on the printer identity acquired from the getReferenceParameterFromMessageContext method to the appropriate printer instances.

 

Use endpoint references to send messages to an endpoint

The client creates a JAX-WS proxy for the printer, and converts the proxy into a BindingProvider object. The client then associates the EndpointReference object obtained previously with the request context of the BindingProvider object, as illustrated in the following example.

import javax.xml.ws.BindingProvider;
...

 javax.xml.ws.Service service= ...;

Printer myPrinterProxy = service.getPort(portName, Printer.class); javax.xml.ws.BindingProvider bp = (javax.xml.ws.BindingProvider)myPrinterProxy; // Retrieve the request context for the BindingProvider object

Map myMap = myBindingProvider.getRequestContext(); // Associate the endpoint reference that represents the new printer to the request context // so that the BindingProvider object now represents a specific printer instance. myMap.put(WSADDRESSING_DESTINATION_EPR, destinationEpr); ...

The BindingProvider object now represents the new printer resource instance, and can be used by the client to send messages to the printer through the Printer Web service. When the client invokes the BindingProvider object, WAS adds appropriate message-addressing properties to the message header, which in this case is a reference parameter contained within the endpoint reference that identifies the target printer resource.

Alternatively, the client can use a JAX-RPC Stub or Call object, which the client configures to represent the new printer. The use of the Call object is illustrated in the following example.

import javax.xml.rpc.Call;
...
 :
 
// Associate the endpoint reference that represents the new printer with the call.
 call.setProperty(
        "com.ibm.websphere.wsaddressing.WSAConstants.
                             WSADDRESSING_DESTINATION_EPR ", epr);

From the perspective of the client, the endpoint reference is opaque. The client cannot interpret the contents of any endpoint reference parameters and should not try to use them in any way. Clients cannot directly create instances of endpoint references because the reference parameters are private to the service provider; clients must obtain endpoint references from the service provider, for example through a provider factory service, and then use them to direct Web service operations to the endpoint that is represented by the endpoint reference, as shown.



 

Related concepts


Web Services Addressing support
Web Services Resource Framework support

 

Related tasks


Create stateful Web services using the Web Services Resource Framework
Use the Web Services Addressing APIs: Creating an application that uses endpoint references

 

Related


Web Services Addressing APIs
IBM proprietary Web Services Addressing SPIs