Version 1
    Since 3.0.2 (Metro)

    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.