Archive for the ‘BizTalk Server’ Category.

System.Net.WebException when issuing more than two concurrent WebRequest’s

I got caught up yesterday with a problem I should have recognized right away, but for whatever reason I didn’t put the pieces together until it was pointed out by one of my co-workers.

I was writing a BizTalk Server 2006 orchestration that, amongst other things, sends a request to a remote server.  The remote server has an application installed that accesses these requests and initiates a few local (and unimportant) processes.  Information is passed to this application via the URL which is unique with each request and constructed by the orchestration.

Rather than use a dynamic one-way send port with the HTTP adapter, I decided to create a .NET helper project (a C# class library) and create a static method that allows me to pass in the URL and wait for a response.  The contents of the response itself is unimportant; all I require is a successful response.

I created the following class in my helper project (simplified for clarity):

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Text;
   4:  using System.Net;
   5:  namespace Messaging.Helper
   6:  {
   7:      [Serializable]
   8:      public class Statics
   9:      {
  10:          public void CallUrl(string url)
  11:          {
  12:              WebRequest request = WebRequest.Create(url);
  13:              request.Method = "GET";
  14:              request.GetResponse();
  15:          }
  16:      }
  17:  }

As you can see, the static method uses the System.Net.WebRequest class to issue a request to the specified URL.  To test this method, I created a command-line application that iterated 20 or so times and issued requests against the remote server.  The code was similar to the following (simplified for clarity):

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Text;
   4:  using System.Net;
   5:  using Messaging.Helper;
   6:  namespace Messaging.ConsoleApp
   7:  {
   8:      class Program
   9:      {
  10:          static void Main(string[] args)
  11:          {
  12:              for (int i = 0; i < 20; i++)
  13:              {
  14:                  Statics.CallUrl("http://www.someurl.com/");
  15:              }
  16:          }
  17:      }
  18:  }

I immediately noticed that this code failed after it issued two concurrent requests.  No matter how many times I ran it, it always was successful the first two times and then timed-out and threw an error message similar to the following:

    System.Net.WebException was unhandled
    Message="The operation has timed out"
    Source="System"
    StackTrace:
      at System.Net.HttpWebRequest.GetResponse()
      at ConsoleApp.Program.Helper.CallUrl() in D:TestConsoleAppProgram.cs:line 41
      at ConsoleApp.Program.Main(String[] args) in D:TestConsoleAppProgram.cs:line 20
      at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
      at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity,
         String[] args)
      at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
      at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
      at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,
         ContextCallback callback, Object state)
      at System.Threading.ThreadHelper.ThreadStart()

Yes, I should have immediately picked up on the fact that it succeeded the first two times but then consistently failed on each additional request.  Instead, I tried all kinds of different scenarios (non-static methods, multi-threaded calls, etc.).  Fortunately, a co-worker stopped by and reminded me that, by design, there is a limit on the number of connections you can have to any given server.  By default, this limitation is set to two!

As soon as he said that I remembered the limitation (I guess I still have a few neurons that occasionally fire).  Immediately I created an application configuration file for my command-line application and added the following (of course, I had to look-up the exact syntax):

   1:  <?xml version="1.0" encoding="utf-8" ?>
   2:  <configuration>
   3:      <system.net>
   4:          <connectionManagement>
   5:              <add address="*" maxconnection="100" />
   6:          </connectionManagement>
   7:      </system.net>
   8:  </configuration>

This allows for up to 100 simultaneous connections to any server.  When I ran my command-line application again it worked perfectly — 20 requests were issued to the URL.

After poking around a little bit, I found the actual specification in the HTTP/1.1 protocol that dictates this limitation.  See Hypertext Transfer Protocol – Section 8.1.4:

"Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users. These guidelines are intended to improve HTTP response times and avoid congestion."

Ah, this explains why Internet Explorer only allows me to download two files at the same time!

Now, in order to allow my BizTalk orchestration to proper issue more than two concurrent connections (remember, it too is just calling .NET code), I needed to modify the BTSNTSvc.exe.config file that services the BizTalk host instances.  This file is found in the BizTalk Server directory under Program Files:

BTSNTSvc.exe.config

Simply add the <system.net> … </system.net> XML to the configuration file and then restart your host instances.  This will allow you to issue more than two concurrent requests to any given web server.

I hope this helps save you some time you would have otherwise lost!

Warning: the CID values for both test machines are the same

I came across a frustrating interesting problem today where the BizTalk Server 2006 Configuration wizard would fail every time I applied a new configuration.

Unlike a typical BizTalk developer environment (which usually consists of BizTalk and SQL Server on the same machine), this environment consisted of two separate machines: one BizTalk Server 2006 and one SQL Server 2005 (i.e. the BizTalk databases are stored on the SQL Server).  Additionally, this is a virtual environment and both machines were cloned from the same base Windows Server 2003 R2 template.

I was installing the following components …

  • Enterprise Single Sign-On (SSO)
  • Group
  • BizTalk Runtime
  • MSMQT

It would successfully install ENTSSO, but would fail when installing the group.  The log file reported the following error:

Failed to configure with error message [Exception of type 'System.EnterpriseServices.TransactionProxyException' was thrown.]

The following Google search suggested to me that  the underlying problem was with MSDTC (aren’t all BizTalk problems?).  I checked, and double-checked, the MSDTC properties on both servers and couldn’t find anything wrong with the configuration.  So, I had to pull out the big guns.

I downloaded DTCPing (a very handy tool for debugging DTC issues) and ran it on both machines (make sure to read the instructions on how to use DTCPing as it is not straightforward).  In the generated log file I noticed the following warning:

WARNING: the CID values for both test machines are the same while this problem won’t stop DTCping test, MSDTC will fail for this …

A Google search on this warning helped me to understand that the underlying problem is that the CID values stored for MSDTC were not changed during the cloning process.  But of course!

If you’re experiencing this problem, check the following registry key on both of your machines.  Are the keys identical?

HKEY_CLASSES_ROOTCID

Mine were.  Here’s the steps I took successfully reinstall MSDTC so that the CID values were unique.  Run this procedure on both machines:

  1. Use Add Windows Components, and remove Network DTC.
  2. Go to the command line and run: MSDTC -uninstall
  3. Go to the registry and delete the MSDTC keys in HKLM/Software/Microsoft/Software/MSDTC, HKLM/System/CurrentControlSet/Services/MSDTC, and HKEY_CLASSES_ROOTCID (if they’re still there).
  4. Reboot
  5. Go to the command line and run: MSDTC -install
  6. Use Add Windows Components, and add Network DTC.
  7. Go to the command line and run: net start msdtc

After running this on both servers I was able to confirm that the CID values were unique.  And, sure enough, when I next applied my configuration to BizTalk Server 2006 everything worked perfectly.

I hope this helps!

BizTalk Server 2006 eConnect Adapters for Great Plains 9.0

I’ve started working on a project that integrates into Great Plains 9.0 using eConnect.  Not having done this using BizTalk Server 2006, I thought I’d document some of my observations and the steps I took.

To begin, I was able to get eConnect for GP (en_econnect_for_gp.zip) through my MSDN subscription.  If you have Great Plains 9.0, then you should be able to get your hands on this package.  When you unzip the package, you’ll notice two files:

  • eConnectInstallAdminGuide.pdf – This is a great document that, if you are going to interact and develop with eConnect, I highly encourage you to read.  There are three parts: eConnect Basics, Installation, and Administration.  At the very least, developers should reach the first part, which includes an overview and architecture chapter.
  • Microsoft_Business_Solutions_eConnect.msi – This is the actual installation file.  Note: it contains MUCH more than just the BizTalk Server adapters.

After reading through the eConnect guide, I ran the installation MSI file.  A few highlights / comments:

  • I chose the “Custom” setup.  I never choose Standard or Complete.
  • My sole purpose at this point is to install the BizTalk adapter with the eConnect schemas; follow the administration guide, instead of this post, if you’re setting up for production.
  • There are a lot of features, including:
    • BizTalk Components – both 2004 and 2006
    • Business Objects – installs the Business Objects into SQL Server
    • COM+ Components – installs COM components and .NET assemblies
    • eConnect Incoming Service – incoming eConnect Win32 service
    • eConnect Outgoing Service – outgoing eConnect Win32 service
    • eConnect Replication Service – eConnect Win32 replication service
    • eConnect Help – help
    • eConnect Samples – .NET and VB6 examples
    • Queue Control – view documents in MSMQ queue
    • Schemas – eConnect XSD and XDR schemas
  • Not knowing any better, I decided to only include the following features:
    • BizTalk Components
    • eConnect Help
    • eConnect Samples
    • Schemas

Once you have installed eConnect 9.0, you must still install the adapters for BizTalk Server.  Browser to the following folder: C:Program FilesMicrosoft Great PlainseConnect9BizTalkBizTalk 2006 (obviously, choose BizTalk 2004 if  you are using 2004).  From here you can run the BTS_eConnectAdapter.msi file and install the BizTalk Server 2006 adapter.

Once the installation for the adapter is complete, make sure you update your platform settings and add the adapter.  Follow these steps:

  1. Open the BizTalk Server 2006 Administration Console.
  2. Go to BizTalk Group -> Platform Settings -> Adapters.
  3. Right-click the Adapters folder, and select New -> Adapter.
  4. Enter a name for the adapter (e.g. eConnect) and select the “Dynamics GP eConnect” adapter from the adapter list.
  5. Click OK.  Make sure you restart your host instances.

Pretty simple and straightforward.

Now, browse to the following folder: C:Program FilesMicrosoft Great PlainseConnect9XML Schemas.  Here you will notice all the XDR and XSD schemas.  In particular, the “Incoming XSD Individual Schemas” and the “Incoming XSD Schemas” folders.  The first has every schema in an individual XSD, whereas the second has them all in an eConnect.xsd file.  Depending on you circumstances, you can import these schemas into your BizTalk projects, so that you can utilize them in Orchestrations, maps, or whatever else you choose.  Additionally, once you deploy your projects assemblies, the schemas will be available within your BizTalk solution.

And finally, one other folder you may want to look at is C:Program FilesMicrosoft Great PlainseConnect9XML Sample DocumentsIncoming.  This folder has a number of sample XML documents that you can use for testing.  VERY useful stuff here!

Just a few things I’ve learned and observed while getting all this configured.  I’m sure I’ll post more as I continue to use the eConnect adapter.

I hope this helps!