Archives

Archives / 2007 / July
  • MTOM interoperability between Oracle App Server and Sun WSIT

    A few months ago I wrote a couple of articles (WCF-ORA, ORA-WCF) about Message Transmission Optimization Mechanism (MTOM) interoperability between Oracle Application Server and Microsoft Windows Communication Foundation (WCF).  Most of the feedback I got from those posts was related with MTOM interoperability scenarios using other Web Service technologies toolkits. Based on that, I decided to post a few more demos that reflect MTOM interoperability scenarios for different vendors. Specifically, this paper shows how to achieve MTOM interoperability between Oracle App Server and Sun Web Service Interoperability Technology (WSIT - Project Tango).  Believe it or not, I am sorry .NET developers; there is no .NET code in this paper.

    This post does not intend to provide a formal introduction to MTOM. Suffice to say that after a few years and three predecessors' specifications, MTOM has become the preferred Standard for SOAP-encoded binary messaging optimization. MTOM relies on the XML Optimized Processing (XOP) Standard as the serialization mechanism to represent binary data as a MIME/Multipart Related package. If you are interested in the importance of MTOM interoperability you might want to read my previous paper or this post by John Evdemon.

    Sun WSIT and MTOM

    WSIT is part of Project Metro which is the Web Services stack from Sun Microsystems. Specifically, WSIT is the component of Project Metro that implements some of the most important WS-* protocols emphasizing in interoperability with Microsoft WCF. Needless to say, that WSIT also interoperates really well with other Web Services technologies including Oracle App Server. At the moment WSIT implements some of the most important WS-* protocols for areas such as Security, Reliability, Transactions and messaging optimization (a.k.a MTOM). The typical scenarios for applying MTOM are Web Services that handles binary data like byte[] as part of their contract. The following code illustrates a WSIT Service that can be highly optimized with the use of MTOM.

    @WebService()
    public class FileWS {

    @WebMethod(action="PrintFileContents")
    public int PrintFileContents(byte[] buffer)
    {
    for(int i=0; i<= buffer.length - 1; i++)
    System.out.println(buffer[i]);
    return buffer.length;
    }
    }

     Now we need to configure the service policy in order to optimize the message exchange using MTOM.  The trick here, in order to achieve interoperability with Oracle App Server, is to remove the default WSIT WS-Addressing settings. This is due to the fact that Oracle App Server and Sun WSIT implement different versions of WS-Addressing. The change is not required if the client side supports MTOM with WS-Addressing 1.0 like WCF does. Also, If you are using a development IDE such as NetBeans there is no need to manually configure the policy except for removing the use of WS-Addressing; instead you can the Web Service configuration editor which provides a nice interface for configuring the different WS-* protocols for a particular service.

    <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="FileWSService" targetNamespace="http://mtomws/" xmlns:tns="http://mtomws/" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsaws="http://www.w3.org/2005/08/addressing" xmlns:wsoma="http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization"
    >
    WSDL components....
    <wsp:Policy wsu:Id="FileWSPortBindingPolicy">
    <wsp:ExactlyOne>
    <wsp:All>
    <!-- <wsaws:UsingAddressing xmlns:wsaws="http://www.w3.org/2006/05/addressing/wsdl"/>-->
    <wsoma:OptimizedMimeSerialization/>
    </wsp:All>
    </wsp:ExactlyOne>
    </wsp:Policy>
    </definitions>

    Now we are ready to deploy the service, for the purposes of this demo we used Sun Glassfish.

    Oracle App Server and MTOM

    Now it's time to implement an Oracle client for the WSIT service created on the previous section. The first natural step is to generate the proxy using the Web Service Proxy Wizard included in JDeveloper or the corresponding command-line tool. In order to interface with WCF using MTOM, the client code should set the MTOM_SUPPORT property to "True" either programmatically or using the configuration file. The following code shows a sample client that interacts with the WCF service created in the previous section

    public static void Test()
    {
    try
    {
    FileTransmitter transmitter= new FileTransmitter();
    byte[] buffer= transmitter.GetImg("c:\\temp\\images\\p1.jpg");
    FileWSPortClient binding= new FileWSPortClient();
    FileWS proxy= binding.getPort();
    ((OracleStub)proxy)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, service url);
    ((OracleStub)proxy)._setProperty(ClientConstants.MTOM_SUPPORT, true);
    int result= proxy.printFileContents(buffer);
    System.out.println(result);
    }
    catch(Exception ex)
    {
    System.out.println(ex.getMessage());
    }
    }

     Messages Messages

    After hosting the WSIT service in Sun Glassfish and running the Oracle client the following message sequence is produced

    POST /MtomServices/FileWSService HTTP/1.1
    Host: localhost:8082
    Connection: Keep-Alive, TE
    TE: trailers, deflate, gzip, compress
    User-Agent: Oracle HTTPClient Version 10h
    SOAPAction: "PrintFileContents"
    Accept-Encoding: gzip, x-gzip, compress, x-compress
    Content-type: multipart/related;type="application/xop+xml";boundary="----=_Part_0_13050435.1185038715262";start="<97b2fe36f9184df3a6fa8792abd9a00c>";start-info="text/xml;charset=UTF-8"
    Content-length: 12849


    ------=_Part_0_13050435.1185038715262
    Content-Type: application/xop+xml;charset=UTF-8;type="text/xml;charset=UTF-8"
    Content-Transfer-Encoding: 8bit
    Content-ID: <97b2fe36f9184df3a6fa8792abd9a00c>

    <?xml version="1.0" encoding="UTF-8" ?>
    <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://mtomws/"><env:Body><ns0:PrintFileContents><arg0><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:b9abc481c3664db8b0b7f842d0886c30"/></arg0></ns0:PrintFileContents></env:Body></env:Envelope>
    ------=_Part_0_13050435.1185038715262
    Content-Type: application/octet-stream
    Content-Transfer-Encoding: binary
    Content-Id: <b9abc481c3664db8b0b7f842d0886c30>

     SOAP request produced by the Oracle client

    Content-Id: <rootpart*74f72fe4-510e-48de-a29a-38896f03901d@example.jaxws.sun.com>
    Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
    Content-Transfer-Encoding: binary


    <?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:PrintFileContentsResponse xmlns:ns2="http://mtomws/"><return>12000</return></ns2:PrintFileContentsResponse></S:Body></S:Envelope>

    SOAP response produced by the Sun WSIT service

    You can notice that the byte[] in the request message its been optimized using MTOM and XOP.

    In the next weeks I will be posting more demos about WS-* protocols interoperability between some of the top Web Services technologies in the market.

    Read more...

  • More on REST vs. WS-*

    There is an interesting debate going on between my friends Ted Neward and David Chappell about REST vs. WS-* complexity. Beyond the political analogy (in which I agreed with Ted) I would like to add my own opinion on the topic.

    One of the main attractive of REST as an ARCHITECTURE STYLE is its simplicity compared with the traditional SOAP-based approach. Simplicity is a great thing but it just can’t be applied to all scenarios.  Aspects like Reliability, Security, Federated Identity, Transactions, etc, represent very complex challenges of SOA solutions. And as we might already know, complex challenges can’t always be addressed with simple solutions. Approaching those challenges with a REST type approach will end up (in the best case) on recreating a REST-based version of the WS-* protocols. I think the whole WADL vs. WSDL 2.0 debate is a good example of my point. Secondly, WS-* protocols always propose transport-agnostic (a.k.a NON HTTP DEPENDENT) solutions to those challenges. Although I agree 100% with my friend Harry Pierson in that REST is an ARCHITECTURE STYLE; the fact of the matter is that almost all the REST-based solutions I’ve seen for addressing things such as Reliability, Security, etc are dependent on HTTP as a transport protocol and consequently are not a viable solution for REST services that don’t use HTTP as a transport which we have plenty of those.

     Some of the most talented people in the distributed systems industry has put a lot of time and effort creating the WS-* protocols. Not taking advantage of those is, in my opinion, just denying all the progress the industry has made trying to build interoperable Standards for addressing some of the top challenges of Service Orientation.  

     

    Read more...

  • Implementing duplex messaging with BizTalk Services

    It is undeniable that the use of BizTalk Services opens up a new set of possibilities for distributed applications. This post is not intended to provide an overview of BizTalk Services. My friend Clemens Vasters and the BizTalk Services team have been doing a fabulous job in that regard. Instead, I’ve decided to start blogging about different messaging scenarios that I have been implementing using BizTalk Services. Particularly, this post is focused on duplex messaging. As you might already know, duplex contracts are one of the features of WCF that allows implement scenarios on which both WCF endpoints exchange message independently.  Duplex messaging becomes difficult to adopt in scenarios on which the two endpoints reside on different organizations (different networks). This is partially given that a real world duplex messaging scenario requires a whole new set of considerations in terms of network resources (opening ports for receiving the callbacks), different security boundaries, etc. This is what makes BizTalk Services an ideal solution for this type of scenario. Now organizations don’t have to spend time and resources implementing the trusting mechanisms with other organizations. Instead they can rely on BizTalk Services for all that.  The following picture might help to clarify my point.

     

     

    Ok, back to the code

    The process of implementing duplex services using BizTalk Services is very similar to the process we follow for traditional WCF services. Let’s take the following duplex contract as an example.

    [ServiceContract(CallbackContract= typeof(IComplexEchoCallback))]

    public interface IComplexEcho

    {

    [
    OperationContract(IsOneWay=true)]void Echo(string msg);

    }

    [
    ServiceContract]

    public interface IComplexEchoCallback

    {

    [
    OperationContract(IsOneWay=true)] void InvalidMessage(string msg);

    }

     

    In the service implementation we use WS-Addressing to get the BizTalk Services endpoint associated with the callback.

    [ServiceBehavior(Namespace = "http://samples.microsoft.com/ServiceModel/Relay/")]

    public class ComplexEchoService: IComplexEcho

    {

    public void Echo(string msg)

    {

      if (msg.Contains("error"))

      {

       OperationContext.Current.OutgoingMessageHeaders.To = OperationContext.Current.IncomingMessageHeaders.ReplyTo.Uri;                                                                               

      IComplexEchoCallback callback = OperationContext.Current.GetCallbackChannel<IComplexEchoCallback>();

      callback.InvalidMessage(msg);

      }

     else

     Console.WriteLine(msg);

    }

    }

     

    The configuration file associated with the host application declares two services endpoints: one for the interactions with BizTalk Services and one for obtaining the metadata associated with the service.

    <configuration>

    <system.serviceModel>

    <bindings>

    <!-- Application Binding -->

    <relayBinding>

    <binding name="default" connectionMode="RelayedDuplex"/>

    </relayBinding>

    </bindings>

    <behaviors>

    <serviceBehaviors>

    <behavior name="ComplexEchoServiceBehavior">

    <serviceMetadata httpGetEnabled="True"/>

    </behavior>

    </serviceBehaviors>

    </behaviors>

    <services>

    <!-- Application Service -->

    <service name="service.ComplexEchoService" behaviorConfiguration="ComplexEchoServiceBehavior">

    <host>

    <baseAddresses>

    <add baseAddress="http://myserver:port/EchoService"/>

    </baseAddresses> </host>

    <endpoint name="RelayEndpoint"

    contract="service.IComplexEcho"

    binding="relayBinding"

    bindingConfiguration="default" address="" />

    <endpoint name="MtdEndpoint"

    contract="IMetadataExchange"

    binding="mexHttpBinding" />

    </service>

    </services> </system.serviceModel>

    </configuration>

     

    The host application of the WCF service uses the CardSpace token provider to communicate with BizTalk Services; so before you run this sample you need to set up the corresponding CardSpace cards

    CardSpaceTokenProvider tokenProvider = new CardSpaceTokenProvider();

    string userName = tokenProvider.GetUserName();

    Uri address = new Uri(String.Format("sb://{0}/services/{1}/EchoService/", RelayBinding.DefaultRelayHostName, userName));

    ServiceHost host = new ServiceHost(typeof(service.ComplexEchoService), address);

    host.Description.Endpoints[0].Behaviors.Add(tokenProvider);

    host.Open();

    Console.WriteLine("Service address: " + address);

    Console.WriteLine("Press [Enter] to exit");

    Console.ReadLine();

    host.Close();

     

    The client implementation is also relatively simple, as you can see in the following code and very similar to traditional WCF duplex clients. As you might notice, we use WS-Addressing to set the callback (ReplyTo) address to a BizTalk Services specific endpoint.

    public class CallbackHandler : IComplexEchoCallback

    {

    public void InvalidMessage(string msg) //callback operation....

    {

    Console.WriteLine(msg);

    }

    }

     

    class Program

    {

    static void Main(string[] args)

    {

    Test();

    }

    private static void Test()

    {

    CardSpaceTokenProvider tokenProvider = new CardSpaceTokenProvider();

    string userName = tokenProvider.GetUserName();

    string serviceUserName = "jesusmrv";

    Uri clientUri = new Uri(String.Format("sb://{0}/services/{1}/client/", RelayBinding.DefaultRelayHostName, userName));

    Uri serviceUri = new Uri(String.Format("sb://{0}/services/{1}/EchoService/", RelayBinding.DefaultRelayHostName, serviceUserName));

    InstanceContext context = new InstanceContext(new CallbackHandler());

    RelayBinding binding = new RelayBinding();

    binding.ClientBaseAddress = clientUri;

    binding.ConnectionMode =
    RelayConnectionMode.RelayedDuplex;

    EndpointAddress address = new EndpointAddress(serviceUri);

    ComplexEchoClient proxy = new ComplexEchoClient(context, binding, address);using (new OperationContextScope((IContextChannel)proxy.InnerChannel))

    {

    OperationContext.Current.OutgoingMessageHeaders.ReplyTo = ((IClientChannel)proxy.InnerChannel).LocalAddress;

    proxy.Echo("error msg1");

    }

    Console.ReadLine();

    }

    }

    }

     

    The key thing to notice is that the neither the service nor the client has to be terribly concerned with the security and communication infrastructure of the solution which are delegated on BizTalk Services instead. Although the example is very simple it might give you an idea of the different messaging scenarios you can implement using BizTalk Services. The complete source code can be downloaded from here…

    Read more...

  • SharePoint BDC, WCF, adapters and more

    I spent the last few weeks working with Joe Klug (BizTalk Server Product Manager) and other members of the Product team on a demo that shows SharePoint Business Data Catalog (BDC) and Windows Communication Foundation (WCF), specifically the WCF LOB Adapters SDK. The demo shows the implementation of a real world manufacturing process combining SharePoint BDC and the WCF LOB adapters SDK to compose data from CRMLive, SAP and Oracle DB. Joe demonstrated  the entire scenario yesterday as part of Steve Guggenheimer’s keynote at the World Wide Partner conference. I will blog more details about the implementation in the next days.

    I really have to thanks Joel Crawford-Smith(our graphic mastermind at TwoConnect) for putting together the the entire online image of Contoso Manufacturing.

    Read more...

  • WS-ReliableMessaging interoperability between Microsoft WCF and Sun WSIT

    As promised I am going to start blogging about the different Web Services interoperability scenarios I represented as part of my session at SOAWorld 2007. I’ve decided to start with a WS-ReliableMessaging scenario interoperability between Windows Communication Foundation (WCF) and Sun Project Tango (WSIT). The complete source code of this example can be downloaded from here. WS-ReliableMessaging (WS-RM) proposes a model based on SOAP messaging to achieve reliable communication between a service and its consumers. Although OASIS recently announced the version 1.1 the current implementations on .NET and Java environments are based on the previous version. As of today, technologies such as Microsoft WCF, BEA WebLogic, Sun WSIT, IBM WebSphere among others provides WS-RM implementations based on SOAP 1.1 and 1.2. However, similarly to other complex WS-* protocols, WS-RM interoperability represents a complex challenge that needs to be addressed in order to promote a wide adoption of this protocol. As I mentioned before there are several vendors that implement WS-RM Feb 2005. For the purposes of this sample I’ve decided to use Sun WSIT as the service provider and Microsoft WCF as the service consumer.

    Show me the code!!

    Implementing the WSIT service

    Creating a Web Service using Sun WSIT is very similar to creating a Java class with a few annotations. The following code illustrated the WSIT service used as part of this demo. Just for this time, I’ve decided to give my readers a break and not implement a calculator so I went with the second most popular service contract in history.

    @WebService()
    public class EchoWS
    {
        @WebMethod(action="Echo")
        public String Echo(String msg)
        {
            return msg;
        } 
    }
     In order to add WS-RM capabilities to the service we have to configure a couple of sections in the Web Service configuration file.
    <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="EchoWSService" targetNamespace="http://ws/" xmlns:tns="http://ws/" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsaws="http://www.w3.org/2005/08/addressing" xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy" xmlns:sunrm="http://sun.com/2006/03/rm"
     >
    Other WSDL elements...
    <service name="EchoWSService">
    <wsdl:port name="EchoWSPort" binding="tns:EchoWSPortBinding"/>
    </service>
    <wsp:Policy wsu:Id="EchoWSPortBindingPolicy">
    <wsp:ExactlyOne>
    <wsp:All>
             <wsaws:UsingAddressing xmlns:wsaws="http://www.w3.org/2006/05/addressing/wsdl"/>
    <wsrm:RMAssertion/>
    <sunrm:Ordered/>
    </wsp:All>
    </wsp:ExactlyOne>
    </wsp:Policy>

    </definitions>
     

    Implementing a WCF client

    The first step for implementing a WCF client for the service created on the previous section is generating a WCF proxy using the svcutil.exe tool. After that, we can create the client logic as its showed in the following code.
    private static void Test()
    {
    SimpleWSClient proxy = new SimpleWSClient();
    Console.WriteLine(proxy.Echo("simple message 1"));
    Console.ReadLine();
    }
     
    Finally we need to configure the client for supporting WS-RM. This is done adding the reliablesession section to the application configuration file. In order to achieve interoperability with Sun WSIT we’ve decided to rely on WS-Addressing 1.1.
    <configuration>
    <system.serviceModel>
    <bindings>
    <customBinding>
    <binding name="SimpleWSPortBinding">
    <reliableSession maxPendingChannels="4" maxRetryCount="8" ordered="true" />
    <!--Soap11WSAddressing10 encoding-->
    <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
    messageVersion="Soap11WSAddressing10" writeEncoding="utf-8" />
    Other configuration elements....
    </binding>
    </customBinding>
    </bindings>
    <client>
    <endpoint address="http://wsitserver/EchoWSService?WSDL"
    binding="customBinding" bindingConfiguration="SimpleWSPortBinding"
    contract="SimpleWS" name="SimpleWSPort" />
    </client>
    </system.serviceModel>
    </configuration>
     

    Show me the messages!!

    After deploying the service (we are using Sun Glassfish as the application server) and running the client the following SOAP message sequence is produced.  The first message, originated by WCF, requests the creation of a WS-RM sequence to group the messages that are going to be exchanged between the WCF client and the WSIT service.
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing">
    <s:Header>
    <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</a:Action>
    <a:MessageID>urn:uuid:c94288be-8c5e-450c-b5c1-9afa3dad727b</a:MessageID>
    <a:To s:mustUnderstand="1">http://localhost:8080/WSApplication/EchoWSService?WSDL</a:To>
    </s:Header>
    <s:Body>
    <CreateSequence xmlns="http://schemas.xmlsoap.org/ws/2005/02/rm">
    <AcksTo>
    <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </AcksTo>
    <Offer>
    <Identifier>urn:uuid:e2addefe-af3c-4eac-af9c-181f8bacc827</Identifier>
    </Offer>
    </CreateSequence>

    </s:Body>
    </s:Envelope>
    WS-RM Create Sequence message request

    After receiving this message the WSIT engine replies with a sequence identifier.
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header>
    <To xmlns="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymous</To>
    <Action xmlns="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2005/02/rm/
    CreateSequenceResponse
    </Action>
    <MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:3b34e870-f77b-4e81-803a-0fdaf7a03bd5</MessageID>
    <RelatesTo xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:c94288be-8c5e-450c-b5c1-9afa3dad727b</RelatesTo>
    </S:Header>
    <S:Body>
    <ns2:CreateSequenceResponse xmlns:ns6="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ns5="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:ns4="http://www.w3.org/2005/08/addressing" xmlns:ns3="http://schemas.microsoft.com/ws/2006/05/rm" xmlns:ns2="http://schemas.xmlsoap.org/ws/2005/02/rm">
    <ns2:Identifier>uuid:70429721-9229-4be5-b3af-0444f8f4e753</ns2:Identifier>
    <ns2:Accept>
    <ns2:AcksTo>
    <ns4:Address>http://localhost:8080/WSApplication/EchoWSService?WSDL</ns4:Address>
    </ns2:AcksTo>
    </ns2:Accept>
    </ns2:CreateSequenceResponse>

    </S:Body>
    </S:Envelope>
    WS-RM Create Sequence response message

    Now the WCF client produces the first message to invoke the Echo operation. The message is sent under the WS-RM session previously created and it is identified by a sequence number.
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing">
    <s:Header>
    <r:Sequence s:mustUnderstand="1">
    <r:Identifier>uuid:70429721-9229-4be5-b3af-0444f8f4e753</r:Identifier>
    <r:MessageNumber>1</r:MessageNumber>

    </r:Sequence>
    <a:Action s:mustUnderstand="1">Echo</a:Action>
    <a:MessageID>urn:uuid:d08a30f1-2364-4823-b7e7-af6f0eb8ebc1</a:MessageID>
    <a:ReplyTo>
    <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
    <a:To s:mustUnderstand="1">http://localhost:8080/WSApplication/EchoWSService?WSDL</a:To>
    </s:Header>
    <s:Body>
    <Echo xmlns="http://ws/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <arg0 xmlns="">simple message 1</arg0>
    </Echo>
    </s:Body>

    </s:Envelope>

    WS-RM Echo request

    Finally the WSIT service produces the Echo response together with the acknowledgement for the Echo request.
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header>
    <To xmlns="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymous</To>
    <Action xmlns="http://www.w3.org/2005/08/addressing">http://ws/EchoWS/EchoResponse</Action>
    <MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:2e5673ab-aa45-495b-9711-51a7f77cd389</MessageID>
    <RelatesTo xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:d08a30f1-2364-4823-b7e7-af6f0eb8ebc1</RelatesTo>
    <ns2:Sequence xmlns:ns4="http://www.w3.org/2005/08/addressing" xmlns:ns3="http://schemas.microsoft.com/ws/2006/05/rm" xmlns:ns2="http://schemas.xmlsoap.org/ws/2005/02/rm">
    <ns2:Identifier>urn:uuid:e2addefe-af3c-4eac-af9c-181f8bacc827</ns2:Identifier>
    <ns2:MessageNumber>1</ns2:MessageNumber>

    </ns2:Sequence>
    <ns2:AckRequested xmlns:ns4="http://www.w3.org/2005/08/addressing" xmlns:ns3="http://schemas.microsoft.com/ws/2006/05/rm" xmlns:ns2="http://schemas.xmlsoap.org/ws/2005/02/rm">
    <ns2:Identifier>urn:uuid:e2addefe-af3c-4eac-af9c-181f8bacc827</ns2:Identifier>
    </ns2:AckRequested>
    <ns2:SequenceAcknowledgement xmlns:ns4="http://www.w3.org/2005/08/addressing" xmlns:ns3="http://schemas.microsoft.com/ws/2006/05/rm" xmlns:ns2="http://schemas.xmlsoap.org/ws/2005/02/rm">
    <ns2:Identifier>uuid:70429721-9229-4be5-b3af-0444f8f4e753</ns2:Identifier>
    <ns2:AcknowledgementRange Upper="1" Lower="1"></ns2:AcknowledgementRange>
    </ns2:SequenceAcknowledgement>

    </S:Header>
    <S:Body>
    <ns2:EchoResponse xmlns:ns2="http://ws/">
    <return>simple message 1</return>
    </ns2:EchoResponse>
    </S:Body>

    </S:Envelope>
    WS-RM Echo response and sequence acknowledgment message

    Well, I hope that looked simple enough for illustrating a very complex WS interoperability problem. Obviously, real world enterprise service present complex message exchange patterns that require a careful design of the WS-RM sequences and acknowledgements.
    One of the things I want to highlight is that although WS-RM represents the best Standard to exchange message in a reliable manner it is JUST NOT ENOUGH!! for real enterprise SOA scenarios. Other factors such as durable services, durable messaging, SLAs agreements among others need to be taken into consideration when comes to designing truly reliable services.

    Where are we?

    WS-RM is the most widely adopted protocol for achieving reliable communications between services and consumers. Although achieving WS-RM interoperability is challenging is different achievable with the current state of the WS-RM implementations. This article has showed how to achieve WS-RM interoperability between Sun WSIT and Microsoft WCF.

    Read more...