Working with Dispatch Objects - 6.2

Talend ESB Service Developer Guide

EnrichVersion
6.2
EnrichProdName
Talend Data Fabric
Talend Data Services Platform
Talend ESB
Talend MDM Platform
Talend Open Studio for ESB
Talend Real-Time Big Data Platform
task
Design and Development
Installation and Upgrade
EnrichPlatform
Talend ESB

Procedure

To use a Dispatch object to invoke a remote service you do the following:

  1. Create a Dispatch object.

  2. Construct a request message.

  3. Call the proper invoke() method.

  4. Parse the response message.

Creating a Dispatch object

To create a Dispatch object do the following:

  1. Create a Service object to represent the wsdl:service element defining the service on which the Dispatch object will make invocations.

  2. Create the Dispatch object using the Service object's createDispatch() method.

    public Dispatch<T> createDispatch(QName portName, 
       java.lang.Class<T> type, Service.Mode mode) throws WebServiceException;

    Note

    If you are using JAXB objects the method signature for createDispatch() is:

    public Dispatch<T> createDispatch(QName portName, 
       javax.xml.bind.JAXBContext context, Service.Mode mode)
       throws WebServiceException;

The following table describes the parameters for createDispatch() .

Parameter

Description

portName

Specifies the QName of the wsdl:port element that represent the service provider on which the Dispatch object will make invocations.

type

Specifies the data type of the objects used by the Dispatch object.

mode

Specifies the usage mode for the Dispatch object.

The code below creates a Dispatch object that works with DOMSource objects in payload mode.

package com.mycompany.demo;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class Client {
   public static void main(String args[]) {
      QName serviceName = new QName("http://org.apache.cxf", 
         "stockQuoteReporter");
      Service s = Service.create(serviceName);

      QName portName = new QName("http://org.apache.cxf", 
         "stockQuoteReporterPort");
      Dispatch<DOMSource> dispatch = s.createDispatch(portName,
         DOMSource.class,
         Service.Mode.PAYLOAD);
   ...
  }
}

Constructing request messages

When working with Dispatch objects requests must be built from scratch. The developer is responsible for ensuring that the messages passed to a Dispatch object match a request that the targeted service provider can process. This requires precise knowledge about the messages used by the service provider and what, if any, header information it requires.

This information can be provided by a WSDL document or an XMLSchema document that defines the messages. While service providers vary greatly there are a few guidelines that can be followed:

  • The root element of the request is based in the value of the name attribute of the wsdl:operation element that corresponds to the operation being invoked.

    Warning

    If the service being invoked uses doc/literal bare messages, the root element of the request will be based on the value of name attribute of the wsdl:part element referred to by the wsdl:operation element.

  • The root element of the request will be namespace qualified.

  • If the service being invoked uses rpc/literal messages, the top-level elements in the request will not be namespace qualified.

    Important

    The children of top-level elements may be namespace qualified. To be certain you will need to check their schema definitions.

  • If the service being invoked uses rpc/literal messages, none of the top-level elements can be null.

  • If the service being invoked uses doc/literal messages, the schema definition of the message determines if any of the elements are namespace qualified.

For more information about how services use XML messages see the WS-I Basic Profile.

Synchronous invocation

For consumers that make synchronous invocations that generate a response, you use the Dispatch object's invoke() method shown bellow.

T invoke(T msg) throws WebServiceException;

The type of both the response and the request passed to the invoke() method are determined when the Dispatch object is created. For example if you created a Dispatch object using createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE) the response and the request would both be SOAPMessage objects.

Note

When using JAXB objects, the response and the request can be of any type the provided JAXBContext object can marshal and unmarshal. Also, the response and the request can be different JAXB objects.

The code below makes a synchronous invocation on a remote service using a DOMSource object.

// Creating a DOMSource Object for the request
DocumentBuilder db = DocumentBuilderFactory.newDocumentBuilder();
Document requestDoc = db.newDocument();
Element root = requestDoc.createElementNS(
   "http://org.apache.cxf/stockExample", "getStockPrice");
root.setNodeValue("DOW");
DOMSource request = new DOMSource(requestDoc);

// Dispatch disp created previously
DOMSource response = disp.invoke(request);
Asynchronous invocation

Dispatch objects also support asynchronous invocations. As with the higher level asynchronous APIs discussed in Chapter 4, Dispatch objects can use both the polling approach and the callback approach.

When using the polling approach the invokeAsync() method returns a Response<t> object that can be periodically polled to see if the response has arrived.

Response <T> invokeAsync(T msg)
throws WebServiceException;

When using the callback approach the invokeAsync() method takes an AsyncHandler implementation that processes the response when it is returned.

Future<?> invokeAsync(T msg, AsyncHandler<T> handler)
throws WebServiceException;

Note

As with the synchronous invoke() method, the type of the response and the type of the request are determined when you create the Dispatch object.

Oneway invocation

When a request does not generate a response, you make remote invocations using the Dispatch object's invokeOneWay() .

void invokeOneWay(T msg)
throws WebServiceException;

The type of object used to package the request is determined when the Dispatch object is created. For example if the Dispatch object is created using createDispatch(portName, DOMSource.class, Service.Mode.PAYLOAD) the request would be packaged into a DOMSource object.

Note

When using JAXB objects, the response and the request can be of any type the provided JAXBContext object can marshal and unmarshal. Also, the response and the request can be different JAXB objects.

The code below makes a one way invocation on a remote service using a JAXB object.

// Creating a JAXBContext and an Unmarshaller for the request
JAXBContext jbc = JAXBContext.newInstance("org.mycompany.StockExample");
Unmarshaller u = jbc.createUnmarshaller();

// Read the request from disk
File rf = new File("request.xml");
GetStockPrice request = (GetStockPrice)u.unmarshal(rf);

// Dispatch disp created previously
disp.invokeOneWay(request);
Operation Determination

When using a Dispatch client with a WSDL file, the operation name will be set under one of the following cases.

  • The javax.xml.ws.handler.MessageContext.WSDL_OPERATION property of the request context is set with the operation QName.

  • The addressing feature is enabled (in the bus or at the endpoint) and there is a matching operation to the payload element.

  • The "find.dispatch.operation" property of the request context is set to Boolean.TRUE and there is a matching operation to the payload element. This property is not set by default. Determining the correct operation will affect the processing such as setting the correct SOAPAction or WS-Addressing's Action.