How to consume an Itinerary Service

I have to admit; -I wasn’t planning on writing seven articles about ESB Guidance. But the documentation does not cover much of this topic, and there are things to take under consideration when working with the itinerary services provided by the ESB Guidance.

Normally when working with Web Services, we are given a URL, which we’ll reference in our Visual Studio project. Adding this reference will give us a proxy class, along with other classes needed to submit the service methods.  For example if the service would have a SubmitOrder(Order order) method, we’d have an Order class to work with.

ESB Guidance comes with both a Web Service and a WCF Service Itinerary On-Ramps. Both versions support One-way- and Two-way messaging scenarios.

Calling an Itinerary Service is a bit different from calling a Web- or WCF Service in a normal fashion. This is because the service methods are not typed to any request or response object.  Each itinerary service method can serve any type of itinerary, which is the actual definition of what the service will do. In other word, part from many practical reasons, it is possible to have only one receive location and one subscribing send port, to serve as all endpoints of your BizTalk solution (please do not read this as an recommendation). For more information about how Itineraries work, see previous post.

So being a consumer of an Itinerary Service, clearly, given a URL is not enough. We also need the schema definitions along with the actual itinerary (xml file).

If you are comfortable with creating the xml message in your code, all you need to do is to add the service reference to your project, create your xml message according to the schema, deserialize the itinerary xml to the Itinerary object and call the service:

static void Sample1()
{
    // Create the Order xml. This is the "object" that is going to be submitted.
    XmlDocument orderXml = new XmlDocument();
    orderXml.Load(@"C:\ESB Guidance\Data\NAOrderDoc.xml");
    
    // Create the Itinerary Xml Document from the file 
    XmlDocument itinararyXml = new XmlDocument();
    itinararyXml.Load(@"C:\ESB Guidance\Itineraries\SubmitOrderItinerary.xml");

    // Calling the WCF Service
    using (ProcessRequestClient wcfClient = 
        new ProcessRequestClient("WSHttpBinding_ITwoWayAsyncVoid"))
    {
        if (wcfClient.State != System.ServiceModel.CommunicationState.Opened)
            wcfClient.Open();

        // Creating the Itinerary
        // Deserialize the OuterXml to the Itinerary object
        StringReader reader = new StringReader(itinararyXml.DocumentElement.OuterXml);
        XmlSerializer ser = new XmlSerializer(typeof(Itinerary), 
            "http://schemas.microsoft.biztalk.practices.esb.com/itinerary");
        Itinerary wcfItinerary = 
            (Itinerary)ser.Deserialize(reader);

        // Submit WCF Call
        wcfClient.SubmitRequest(wcfItinerary, orderXml.OuterXml);
        wcfClient.Close();
    }

    
    // Same as above but calling the Web Service
    using (asmxItineraryOneWay.Process svc = 
        new asmxItineraryOneWay.Process())
    {
        svc.Credentials = System.Net.CredentialCache.DefaultCredentials;

        // Creating the Itinerary
        // Deserialize the OuterXml to the Itinerary object
        StringReader reader = new StringReader(itinararyXml.DocumentElement.OuterXml);
        XmlSerializer ser = new XmlSerializer(typeof(asmxItineraryOneWay.Itinerary), 
            "http://schemas.microsoft.biztalk.practices.esb.com/itinerary");
        asmxItineraryOneWay.Itinerary asmxItinerary = 
            (asmxItineraryOneWay.Itinerary)ser.Deserialize(reader);

        // Set the ItineraryValue
        svc.ItineraryValue = asmxItinerary;

        XmlNode orderXmlNode = (XmlNode)orderXml;
        svc.SubmitRequest(orderXmlNode);
    }

}

However, you could use Xsd.exe or XsdObjectGen.exe to create the Order class, to submit to the service method. I also created a sample ItineraryFactory class to help deserialize the Itinerary and to serialize the Order object:

static void Sample2()
{
    // Create the Order object.
    OrderDoc order = new OrderDoc();
    order.customerName = "Microsoft";
    order.ID = 1;
    order.requestType = 10;

    // Create the Itinerary
    string itineraryXml = @"C:\ESB Guidance\Itineraries\SubmitOrderItinerary.xml";
    Itinerary itinerary = ItinaryFactory.Load(itineraryXml);

    // Serialize the Order object to string
    string data = ItinaryFactory.SerializeToString(order);
    
    using (ProcessRequestClient client = new ProcessRequestClient("WSHttpBinding_ITwoWayAsyncVoid"))
    {
        if (client.State != System.ServiceModel.CommunicationState.Opened)
            client.Open();
        client.SubmitRequest(itinerary, data);
        client.Close();
    }
}