Sunday, August 25, 2013

Publishing messages to BizTalk Database using WCF-NetTcp (Or any other WCF adapter)

Our BizTalk team ran into a very intresting scenario at work.

We have a clustered host in two different BizTalk environments, and we needed to receive a message via WCF, and deliver it to the relavent host's messagebox.

At first glance, we thought about writing a web-service which will publish to the messagebox, and will be hosted by the IIS.
That option wasn't good enough, because IIS should be installed on the same machine as BizTalk Server in order to interact with it (and that means we can't use clustering).

So we thought about not using the IIS for hosting, and found out that BizTalk allows you to host WCF service inside BTSNTSvc.exe (BizTalk Process).


How to do it ?


1. Create a receive location with "WCF-NetTcp" adapter, and configure a service address.
Note that this address (or service) doesn't even exist. You didn't need to actually write that WCF service.

Now you can send messages to the BizTalk message box using that service. Ofcourse, we could have used any other WCF adapter in order to achieve this functionallity.



2. Once you did the first step, and the receive location is running - you can access it by a client.
Here is the console application client I wrote, which sends a message to the WCF Service (actually to the BizTalk Message Box):

App.config


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NetTcpBindingEndpoint" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
            hostNameComparisonMode="StrongWildcard" listenBacklog="10"
            maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
            maxReceivedMessageSize="65536">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
              enabled="false" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
            <message clientCredentialType="Windows" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://SOMEDOMAIN.COM/MyTestService/SendToMsgBox.svc"
          binding="netTcpBinding" bindingConfiguration="NetTcpBindingEndpoint"
          contract="IService1" name="NetTcpBindingEndpoint">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

IService.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName = "IService1", Namespace ="http://BTS.WebServices.Test/")]   
    public interface IService1
    {
        [System.ServiceModel.OperationContractAttribute(Action = "http://BTS.WebServices.Test/IService1/SendToMsgBox", ReplyAction = "http://BTS.WebServices.Test/IService1/SendToMsgBox")]
        void SendToMsgBox(System.Xml.XmlElement part);
    }
}


Service1Client.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public class Service1Client : System.ServiceModel.ClientBase<IService1>, IService1
    {
        public Service1Client()
        {
        }

        public void SubmitRequest(System.Xml.XmlElement request)
        {
            base.Channel.SendToMsgBox(request);
        }
    }
}
Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Service1Client client = new Service1Client();

            System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
            xmlDoc.Load(@"C:\SomeFileToSendToBizTalkMsgBox.xml");            
            client.SendToMsgBox(xmlDoc.DocumentElement);

            client.Close();

        }
    }
}

Thank you Blogger, hello Medium

Hey guys, I've been writing in Blogger for almost 10 years this is a time to move on. I'm happy to announce my new blog at Med...