Service Provider Implementation
The service provider implementation may be done using JAX-WS. In such case, the provider side method in the annotated interface may look like this:
Library JAX-WS annotated interface
@WebService(targetNamespace = "http://services.talend.org/demos/Library/1.0",
name = "Library")
@XmlSeeAlso({org.talend.types.demos.library.common._1.ObjectFactory.class,
org.talend.types.demos.generalobjects.errorhandling._1.ObjectFactory.class})
public interface Library {
...
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@Oneway
@WebMethod(action = "seekBookInBasement")
public void seekBookInBasement(
@WebParam(partName = "body", name = "SearchInBasementFor",
targetNamespace = "http://types.talend.org/demos/Library/Common/1.0")
org.talend.types.demos.library.common._1.SearchInBasementFor body
);
...
}
A JAX-WS client must be created on the provider side to send a callback because the callback message is sent to a separate endpoint opened on the consumer side. The Client object may be set up as a jaxws:client bean in Spring configuration.
Provider side jaxws:client configuration example
<jaxws:client xmlns:library="http://services.talend.org/demos/Library/1.0"
id="callbackResponseClient" serviceName="library:LibraryConsumer"
endpointName="library:LibraryConsumerPort" address="jms://"
serviceClass="org.talend.services.demos.library._1_0.LibraryConsumer">
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature"/>
</jaxws:features>
</jaxws:client>
The Client needs the Talend ESB CallContext feature to be set up as well as a service provider to work properly. CallContext class has a method that helps to set up callback proxy object. The method is called setupCallbackProxy and after it was applied to the proxy object, the proxy is ready to work.
Each request-callback message has a call context object associated with it. Call context is necessary for proper handling of request-callback messages. Call context object contains such information as call id, callback id, address of endpoint to which reply should be sent, and so on. The class org.talend.esb.mep.requestcallback.feature.CallContext is used to represent call context objects. It is necessary to extract call context from a message when handling request, at least to provide call id of the message to which callback message is related to.
In the example above, the callback proxy object was injected into the service provider and the callback was sent from the same thread in which request was received. In real-world scenarios, it is a rare situation, it is here just for the example purpose.
The request-callback processing on the provider side is shown below:
Request-Callback processing on provider side example
public class LibraryServerImpl implements Library {
...
// Injected jaxws:client (see xml config above)
private LibraryConsumer callbackResponseClient;
@Resource
private WebServiceContext wsContext;
@Override
public void seekBookInBasement(SearchInBasementFor body) {
// Extract call context from message
CallContext ctx = CallContext.getCallContext(wsContext.getMessageContext());
// Some business logic here
ListOfBooks result = new ListOfBooks();
BookType book = new BookType();
result.getBook().add(book);
PersonType author = new PersonType();
book.getAuthor().add(author);
author.setFirstName("John");
author.setLastName("Stripycat");
Calendar dateOfBirth = new GregorianCalendar(202, Calendar.MAY, 17);
author.setDateOfBirth(dateOfBirth.getTime());
book.getTitle().add("Hunting basement inhabitants");
book.getPublisher().add("Dusty Edition");
book.setYearPublished("2013");
// Set up necessary interceptors for callback proxy object
ctx.setupCallbackProxy(callbackResponseClient);
// Send callback message back to client
callbackResponseClient.seekBookInBasementResponse(result);
}
...
}