Metro comes with support for both WS-RM 1.0 and WS-RM 1.1. In this sample we will show how to create client and endpoint communicating each other using WS-RM 1.1 The sample uses WS-Policy specification to configure WS-RM.
Creating the WS-RM based service and client is very simple. User needs to create regular JAX-WS service and client first. The last step is to configure WSRM.
The service
We will start with the following endpoint implementation (bottom-up approach):
package org.jboss.test.ws.jaxws.samples.wsrm.service; import javax.jws.Oneway; import javax.jws.WebMethod; import javax.jws.WebService; @WebService ( name = "SimpleService", serviceName = "SimpleService", wsdlLocation = "WEB-INF/wsdl/SimpleService.wsdl" targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsrm" ) public class SimpleServiceImpl { @Oneway @WebMethod public void ping() { System.out.println("ping()"); } @WebMethod public String echo(String s) { System.out.println("echo(" + s + ")"); return s; } }
Let's say that compiled endpoint class is in directory /home/username/wsrm/metro/classes. Our next step is to generate JAX-WS artifacts and WSDL.
Generating WSDL and JAX-WS Endpoint Artifacts
We will use wsprovide commandline tool to generate WSDL and JAX-WS artifacts. Here's the command:
cd $JBOSS_HOME/bin ./wsprovide.sh --keep --wsdl \ --classpath=/home/username/wsrm/metro/classes \ --output=/home/username/wsrm/metro/wsprovide/generated/classes \ --resource=/home/username/wsrm/metro/wsprovide/generated/wsdl \ --source=/home/username/wsrm/metro/wsprovide/generated/src \ org.jboss.test.ws.jaxws.samples.wsrm.service.SimpleServiceImpl
The above command generates the following artifacts:
# compiled classes ls /home/username/wsrm/metro/wsprovide/generated/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/ Echo.class EchoResponse.class Ping.class # java sources ls /home/username/wsrm/metro/wsprovide/generated/src/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/ Echo.java EchoResponse.java Ping.java # contract artifacts ls /home/username/wsrm/metro/wsprovide/generated/wsdl/ SimpleService.wsdl SimpleService_schema1.xsd
All aforementioned generated artifacts will be part of endpoint archive. The endpoint archive consists of the following files:
jar -tvf jaxws-samples-wsrm.war 0 Fri Apr 11 20:10:22 CEST 2008 META-INF/ 106 Fri Apr 11 20:10:20 CEST 2008 META-INF/MANIFEST.MF 0 Fri Apr 11 20:10:22 CEST 2008 WEB-INF/ 591 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/web.xml 0 Fri Apr 11 20:10:22 CEST 2008 WEB-INF/classes/ 0 Fri Apr 11 20:10:16 CEST 2008 WEB-INF/classes/org/ 0 Fri Apr 11 20:10:16 CEST 2008 WEB-INF/classes/org/jboss/ 0 Fri Apr 11 20:10:16 CEST 2008 WEB-INF/classes/org/jboss/test/ 0 Fri Apr 11 20:10:18 CEST 2008 WEB-INF/classes/org/jboss/test/ws/ 0 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/ 0 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/ 0 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/ 0 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/ 0 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/ 1235 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/SimpleServiceImpl.class 995 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/Echo.class 1043 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/EchoResponse.class 679 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/Ping.class 0 Fri Apr 11 20:10:22 CEST 2008 WEB-INF/wsdl/ 2465 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/wsdl/SimpleService.wsdl 802 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/wsdl/SimpleService_schema1.xsd
The content of web.xml file is:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>SimpleService</servlet-name> <servlet-class>org.jboss.test.ws.jaxws.samples.wsrm.service.SimpleServiceImpl</servlet-class> </servlet> <servlet-mapping> <servlet-name>SimpleService</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
Generating JAX-WS Client Artifacts
Before we will write regular JAX-WS client we need to generate client artifacts from WSDL. Here's the command to achieve that:
cd $JBOSS_HOME ./wsconsume.sh --keep \ --package=org.jboss.test.ws.jaxws.samples.wsrm.generated \ --output=/home/username/wsrm/metro/wsconsume/generated/classes \ --source=/home/username/wsrm/metro/wsconsume/generated/src \ /home/username/wsrm/metro/wsprovide/generated/wsdl/SimpleService.wsdl
The above command generates the following artifacts:
# compiled classes ls /home/username/wsrm/metro/wsconsume/generated/classes/org/jboss/test/ws/jaxws/samples/wsrm/generated/ Echo.class EchoResponse.class ObjectFactory.class package-info.class Ping.class SimpleService.class SimpleService_Service.class # java sources ls /home/username/wsrm/metro/wsconsume/generated/src/org/jboss/test/ws/jaxws/samples/wsrm/generated/ Echo.java EchoResponse.java ObjectFactory.java package-info.java Ping.java SimpleService.java SimpleService_Service.java
Now the last step is to write the regular JAX-WS client using generated artifacts.
Writing Regular JAX-WS Client
The following is the regular JAX-WS client using generated artifacts:
package org.jboss.test.ws.jaxws.samples.wsrm.client; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; import org.jboss.test.ws.jaxws.samples.wsrm.generated.SimpleService; public final class SimpleServiceTestCase { private static final String serviceURL = "http://localhost:8080/jaxws-samples-wsrm/SimpleService"; public static void main(String[] args) throws Exception { QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wsrm", "SimpleService"); URL wsdlURL = new URL(serviceURL + "?wsdl"); Service service = Service.create(wsdlURL, serviceName); SimpleService proxy = (SimpleService)service.getPort(SimpleService.class); proxy.ping(); // one way call proxy.echo("Hello World!"); // request responce call } }
Now we have both endpoint and client implementation but without WSRM in place. Our next goal is to turn on WS-RM feature.
Turning on WS-RM 1.1
In order to turn on WS-RM in JBossWS-Metro three steps are necessary:
- extend WSDL with WS-Policy containing both WSRM and WS-Addressing policy
- provide endpoint wsit configuration file
- update client code to close the sequence
Extending WSDL
To activate WSRM we need to extend WSDL with WSRM and addressing policy. Here is how it looks like:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <definitions targetNamespace="http://www.jboss.org/jbossws/ws-extensions/wsrm" name="SimpleService" xmlns:tns="http://www.jboss.org/jbossws/ws-extensions/wsrm" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- Created WS-Policy with WSRM addressing assertions --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - --> <wsp:UsingPolicy/> <wsp:Policy wsu:Id="wsrm11policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <wsp:All> <wsp:ExactlyOne> <wsp:All> <ns1:RMAssertion xmlns:ns1="http://docs.oasis-open.org/ws-rx/wsrmp/200702"/> <ns2:UsingAddressing xmlns:ns2="http://www.w3.org/2006/05/addressing/wsdl"/> </wsp:All> </wsp:ExactlyOne> </wsp:All> </wsp:Policy> <types> <xsd:schema> <xsd:import namespace="http://www.jboss.org/jbossws/ws-extensions/wsrm" schemaLocation="SimpleService_schema1.xsd"/> </xsd:schema> </types> <message name="ping"> <part name="parameters" element="tns:ping"/> </message> <message name="echo"> <part name="parameters" element="tns:echo"/> </message> <message name="echoResponse"> <part name="parameters" element="tns:echoResponse"/> </message> <portType name="SimpleService"> <operation name="ping"> <input message="tns:ping"/> </operation> <operation name="echo"> <input message="tns:echo"/> <output message="tns:echoResponse"/> </operation> </portType> <binding name="SimpleServicePortBinding" type="tns:SimpleService"> <!-- - - - - - - - - - - - - - - - - - - - --> <!-- Associated WS-Policy with the binding --> <!-- - - - - - - - - - - - - - - - - - - - --> <wsp:PolicyReference URI="#wsrm11policy"/> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="ping"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> </operation> <operation name="echo"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="SimpleService"> <port name="SimpleServicePort" binding="tns:SimpleServicePortBinding"> <soap:address location="REPLACE_WITH_ACTUAL_URL"/> </port> </service> </definitions>
We added wsp:UsingPolicy, wsp:Policy and wsp:PolicyReference elements to WSDL.
Providing Endpoint wsit Configuration File Containing WS-Policy
In order to activate WSRM in JBossWS-Metro integration user have to provide wsit configuration file. The wsit configuration file naming convention has the following format:
wsit-endpointname.xml so in our case wsit-org.jboss.test.ws.jaxws.samples.wsrm.service.SimpleServiceImpl.xml
The content of wsit configuration file in our sample has the following content:
<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="SimpleService" targetNamespace="http://www.jboss.org/jbossws/ws-extensions/wsrm" xmlns:tns="http://www.jboss.org/jbossws/ws-extensions/wsrm" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- Created WS-Policy with WSRM addressing assertions --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - --> <wsp:Policy wsu:Id="wsrm11policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <wsp:All> <wsp:ExactlyOne> <wsp:All> <ns1:RMAssertion xmlns:ns1="http://docs.oasis-open.org/ws-rx/wsrmp/200702"/> <ns2:UsingAddressing xmlns:ns2="http://www.w3.org/2006/05/addressing/wsdl"/> </wsp:All> </wsp:ExactlyOne> </wsp:All> </wsp:Policy> <message name="ping"/> <message name="echo"/> <message name="echoResponse"/> <portType name="SimpleService"> <operation name="ping"> <input message="tns:ping"/> </operation> <operation name="echo"> <input message="tns:echo"/> <output message="tns:echoResponse"/> </operation> </portType> <binding name="SimpleServicePortBinding" type="tns:SimpleService"> <!-- - - - - - - - - - - - - - - - - - - - --> <!-- Associated WS-Policy with the binding --> <!-- - - - - - - - - - - - - - - - - - - - --> <wsp:PolicyReference URI="#wsrm11policy"/> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="ping"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> </operation> <operation name="echo"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="SimpleService"> <port name="SimpleServicePort" binding="tns:SimpleServicePortBinding"> <soap:address location="REPLACE_WITH_ACTUAL_URL"/> </port> </service> </definitions>
Note
It is very simple to create this file manually. User can see it's the content of wsdl file but with omited types section and empty message elements.
The last step is to include this wsit configuration file in WEB-INF directory of the endpoint archive.
jar -tvf jaxws-samples-wsrm.war 0 Fri Apr 11 20:10:22 CEST 2008 META-INF/ 106 Fri Apr 11 20:10:20 CEST 2008 META-INF/MANIFEST.MF 0 Fri Apr 11 20:10:22 CEST 2008 WEB-INF/ 591 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/web.xml 0 Fri Apr 11 20:10:22 CEST 2008 WEB-INF/classes/ 0 Fri Apr 11 20:10:16 CEST 2008 WEB-INF/classes/org/ 0 Fri Apr 11 20:10:16 CEST 2008 WEB-INF/classes/org/jboss/ 0 Fri Apr 11 20:10:16 CEST 2008 WEB-INF/classes/org/jboss/test/ 0 Fri Apr 11 20:10:18 CEST 2008 WEB-INF/classes/org/jboss/test/ws/ 0 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/ 0 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/ 0 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/ 0 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/ 0 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/ 1235 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/SimpleServiceImpl.class 995 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/Echo.class 1043 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/EchoResponse.class 679 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/Ping.class 2656 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/wsit-org.jboss.test.ws.jaxws.samples.wsrm.service.SimpleServiceImpl.xml 0 Fri Apr 11 20:10:22 CEST 2008 WEB-INF/wsdl/ 2465 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/wsdl/SimpleService.wsdl 802 Fri Apr 11 20:10:20 CEST 2008 WEB-INF/wsdl/SimpleService_schema1.xsd
Updating Client Code to Close the Sequence
The last step is to update client to close the sequences on exit. Here's the updated client code:
package org.jboss.test.ws.jaxws.samples.wsrm.client; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; import org.jboss.test.ws.jaxws.samples.wsrm.generated.SimpleService; import com.sun.xml.ws.Closeable; public final class SimpleServiceTestCase { private static final String serviceURL = "http://localhost:8080/jaxws-samples-wsrm/SimpleService"; public static void main(String[] args) throws Exception { QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wsrm", "SimpleService"); URL wsdlURL = new URL(serviceURL + "?wsdl"); Service service = Service.create(wsdlURL, serviceName); SimpleService proxy = (SimpleService)service.getPort(SimpleService.class); proxy.ping(); // one way call proxy.echo("Hello World!"); // request responce call ((Closeable)proxy).close(); } }
And that's all. Now user have both endpoint and client using WS-RM 1.1 when communicating each other.
Turning on WS-RM 1.0
In order to turn on WS-RM 1.0 in JBossWS-Metro the rules for activating WS-RM 1.1 applies but user have to use http://schemas.xmlsoap.org/ws/2005/02/rm/policy namespace instead of http://docs.oasis-open.org/ws-rx/wsrmp/200702 for WSRM assertions in both WSDL and wsit configuration file. For further information see this link.
Sample Sources
All sources from this tutorial are part of JBossWS-Metro distribution.
Comments