30 Dec 2008

As promised, here is the follow up of my previous post: Calling One Way WCF Service with BizTalk WCF Adapter, Part 1.

Let's do a qui recap: we want to create a WCF proxy that will call a one way web service and return an empty message to BizTalk so the messaging process doesn't timeout waiting for an answer.

The Interface

The first step is to create a service interface that is able to receive any message. This is done by

[ServiceContract(Namespace = "http://pvle.be/WcfOneWayProxy", Name = "OneWayProxy")]
public interface IOneWayProxy
{
    [OperationContract(Action = "*", ReplyAction = "*")]
    Message ProcessOneWayMessage(Message message);
}

The operation has to be defined as a request/reply operation, as this is what BizTalk expects. Note the Action property of the OperationContractAttribute, its value is set to "*" meaning that all received messages will be dispatched to that operation.

The Implementation

Now that the interface is ready, let's implement it.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ValidateMustUnderstand = false)]
public class OneWayProxy : IOneWayProxy
{
    private const String ConfigurationName = "ServiceEndpoint";
    private static ChannelFactory<IOutputChannel> Factory;

    static OneWayProxy()
    {
        BasicHttpBinding binding = new BasicHttpBinding();
        OneWayProxy.Factory = new ChannelFactory<IOutputChannel>(OneWayProxy.ConfigurationName);
        OneWayProxy.Factory.Open();
    }

    #region IOneWayProxy Members

    public Message ProcessOneWayMessage(Message message)
    {
        IOutputChannel channel = OneWayProxy.Factory.CreateChannel();

        try
        {
            //Send the one way message
            channel.Open();
            channel.Send(message);
            channel.Close();
        }
        catch (Exception)
        {
            //Do something, log the exception, whatever

            return Message.CreateMessage(message.Version, "http://pvle.be/EmptyReplyAction");
        }

        //Whatever happens, send a response as this was "Fire and Forget" for the caller
        //Empty response send back to BizTalk so messaging process can terminate gracefully
        return Message.CreateMessage(message.Version, "http://pvle.be/EmptyReplyAction");
    }

    #endregion
}

A couple of remarks here:

  • You need to have a valid client endpoint configuration in you App.config/Web.config that has the name defined in the ConfigurationName const.
  • To create the message that is to be returned, we use the received message's Version property, ensuring that there is no version mismatch.

Now that we have our service implementation, we can host it. I hosted it in IIS, as this is probably the best way to host WCF services and as this proxy should be running all the time.

BizTalk WCF Adapter Configuration

The last step is to make sure that your one way WCF adapter is calling the proxy. This is done by changing the address in the WCF Adapter configuration in your BizTalk project.

BizTalkWcfAdapterConfiguration

Once this is set (the SOAP Action header remains the same), you are ready to run you orchestration. You will see that the messaging process will no longer timeout, as our home made proxy will send an empty response message.

Improvements

Let's face it, this implementation is fine for a proof of concept, but it's hardly enough for a real application as only one endpoint is defined in the configuration.

If you have multiple one way endpoints and you want to reuse that proxy, you'll probably need to have some lookup table in the proxy code to define the destination of the call, based on the To property of the Message object. This way, you can use a single one way proxy for all the actions needed in your orchestrations, as long as you are not using the same action for more than one endpoint.



blog comments powered by Disqus