This post is about configuring a web application that acts as a web service client deployed on Jboss 5.1.0 GA .
The reason for preparing this post is that altough parts of this information exist in various forums and in the CXF documentation, we were unable to find a single place to summarize all necessary steps so far.
The actual web service is another application running on a Weblogic 10.3 cluster. The main WS-RM related characteristics are directly encoded in the WSDL:
1. A policy has been defined to specify the related WS-RM characteristics:
<wsp:Policy wsu:Id="wsrm10policy">
<wsp:ExactlyOne>
<wsp:All>
<wsam:Addressing>
<wsp:Policy />
</wsam:Addressing>
<wsrmp:RMAssertion xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
<wsrmp:BaseRetransmissionInterval
Milliseconds="4000" />
<wsrmp:DeliveryAssurance>
<wsp:Policy>
<wsp:All>
<wsrmp:ExactlyOnce />
<wsrmp:InOrder />
</wsp:All>
</wsp:Policy>
</wsrmp:DeliveryAssurance>
</wsrmp:RMAssertion>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
2. The policy is referenced in the binding of our Web Service:
<wsdl:binding name="AsyncDeliveryRMServiceSoapBinding" type="tns:AsyncDeliveryRMServicePortType">
<wsp:PolicyReference URI='#wsrm10policy' />
. . . . . .
</wsdl:binding>
The focus of this post is on the client side (Jboss). The following steps outline the WS-RM specific configuration:
- Use the server WSDL to generate the required artifacts (Web Service interface, etc.) using wsdl2java.
- Configure a jaxws:client and a decoupled endpoint to receive WS-RM responses:
- Add the following dependencies in the pom.xml of the Maven project (notice the inclusion of cxf-rt-transports-http-jetty as it is necessary for the decoupled endpoint to be created) :
<jaxws:client id="asyncRMClient"
xmlns:h="http://namespace.my/"
serviceClass="my.namespace. AsyncDeliveryRMServicePortType"
serviceName="h:AsyncDeliveryRMService"
endpointName="h:AsyncDeliveryRMServicePort"
wsdlLocation="http://192.168.56.120/wsserver/AsyncDeliveryRMService?wsdl"
>
. . . . .
</jaxws:client>
<http:conduit name="{http://namespace.my/}AsyncDeliveryRMServicePort.http-conduit">
<http:client DecoupledEndpoint="http://192.168.56.1:9990/decoupled_endpoint"/>
</http:conduit>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-rm</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-addr</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-policy</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-common-utilities</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
<exclusions>
<exclusion>
<artifactId>geronimo-servlet_2.5_spec</artifactId>
<groupId>org.apache.geronimo.specs</groupId>
</exclusion>
</exclusions>
</dependency>
- Create a class (RMRequestPoster in our case) to invoke the client configured above and wire this dependency in the Spring configuration:
<bean
class="my.sender.RMRequestPoster"
id="rmRequestPoster">
<property name="rmPort">
<ref bean="asyncRMClient"/>
</property>
</bean>
- Add code to invoke the service:
public class RMRequestPoster {
. . . .
//This is the jaxws:client configured in step 3
private AsyncDeliveryRMServicePortType rmPort;
. . . .
public void postRequest() {
//Perform any application specific actions
. . . . .
//Invoke a one-way operation on the port
rmPort.postMessage(<required parameters>);
. . . . . .
}
}
- IMPORTANT: Copy jetty.jar and jetty-util.jar under <%JBOSS_HOME%>/server/<your server>/deployers/ jbossws.deployer
- If the decoupled endpoint must operate behind a proxy, it may be necessary to change the replyTo address in the WS-Addressing headers. An interceptor can be used to achieve this:
public class ReplyToInterceptor extends AbstractPhaseInterceptor<Message>
{
public ReplyToInterceptor() {
super(Phase.PRE_LOGICAL);
addAfter(MAPAggregator.class.getName());
}
@Override
public void handleMessage(Message message) {
AddressingProperties maps = ContextUtils.retrieveMAPs(message, false,
true);
EndpointReferenceType replyTo = maps.getReplyTo();
replyTo.getAddress().setValue(
"http://192.168.56.1:9999/decoupled_endpoint");
}
}