+

Search Tips   |   Advanced Search

 

Example: Creating a Web service that uses the 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 Web Services Addressing (WS-Addressing) APIs that are provided by WAS.

 

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 returns the EndpointReference object, which now represents the new printer.

import com.ibm.websphere.wsaddressing.EndpointReferenceManager; import com.ibm.websphere.wsaddressing.EndpointReference;
... public Constants
{

// 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 EndpointReference createPrinter(java.lang.Object createPrinterRequest)
{
 // 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 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 WebSphere Application Server processes properties these 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 MessageContext 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 obtains a JAX-RPC Stub object in the normal Java Platform, Enterprise Edition (Java EE) way by looking up the Printer service in the Java Naming Directory Interface (JNDI). The client then associates the EndpointReference object obtained previously with the Stub object, as illustrated in the following example.

import javax.xml.rpc.Stub;
...
 // Associate the endpoint reference that represents the new printer with the Printer stub. 
 Printer p = (Printer)((new PrinterServiceLocator()).getPort(Printer.class));
 Stub printerStub = (javax.xml.rpc.Stub)p;
 printerStub._setProperty(
        "com.ibm.websphere.wsaddressing.WSAConstants.
                             WSADDRESSING_DESTINATION_EPR ", epr);

The Stub 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 Stub object, WebSphere Application Server 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 Call object, which the client configures to represent the new printer as 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


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

 

Related Reference


Web Services Addressing APIs
Web Services Addressing SPI

 

Reference topic