Interesting tech stuff I come across day-to-day. Mainly around Biztalk and .NET 3.0

Determine whether the BizTalk assembly is Debug or Release build at runtime.

Saturday, June 02, 2007

Recently someone raised this question in the newsgroup, they wanted to branch inside the orchestration based on the build of the assembly itself. Whenever an assembly is build with "Debug" mode, some System.Diagnostics.DebuggableAttributes are added to the assembly. One such attribute is "IsJITTrackingEnabled", which will track information during code generation (MSIL) for the debugger.

So, we can use the simple technique of reflection to determine whether the assembly is build against "Debug" or "Release" mode by the presence or absence of IsJITTrackingEnabled attribute. The below method does exactly the same:

public static bool IsDebugBuild(System.Reflection.Assembly assembly)
{
object[] attributes = assembly.GetCustomAttributes(typeof(DebuggableAttribute), false);

if (attributes.Length == 0)
return false;//No debug attibutes, so release build

foreach (Attribute attr in attributes)
{
if (attr is DebuggableAttribute)
{
DebuggableAttribute d = attr as DebuggableAttribute;
if (d.IsJITTrackingEnabled == true) //this flag is set only for debug builds
return true; //Debug
else
return false; //Release
}
}
throw new Exception("Cannot determine the build type");
}

Place the above code in an utility class (external assembly), build and GAC it. Inside your Orchestration, reference the assembly, define a variable (ex: assm) of type "System.Reflection.Assembly" and call the method IsDebugBuild as shown below inside your Expression shape

assm = System.Reflection.Assembly.GetExecutingAssembly();
System.Diagnostics.Debug.WriteLine(Utility.DetermineDebugOrRelease.IsDebugBuild(assm));

Place the above code in an utility class (external assembly), build and GAC it. Inside your Orchestration, reference the assembly, define a variable (ex: assm) of type "System.Reflection.Assembly" and call the method IsDebugBuild as shown below inside your Expression shape

assm = System.Reflection.Assembly.GetExecutingAssembly();
System.Diagnostics.Debug.WriteLine(Utility.DetermineDebugOrRelease.IsDebugBuild(assm));

NOTE: This example is just to address someone's question. You should try NOT to use this type of code in production. Because reflection is an expensive process and it doesn't really suits well for high throughput BizTalk applications.

Nandri!
Saravana

Labels:




BizTalk 2006 R2 - consume an .ASMX webservice using WCF-BasicHttp adapter

Thursday, May 31, 2007

Normally when we need to consume a .asmx web service in BizTalk 2004/2006 (NOT R2) inside an orchestration, we add a web reference, which will create all the multi-part message and web port type required to consume the orchestration. You construct the orchestration and configure the SOAP adapter in the send port to consume the web service. I suppose that's the normal route any BizTalk developer will take when you are put under a circumstance to consume an .asmx webservice using WCF-BasicHttp adapter.

But when you are going to use the WCF-BasicHttp adapter, "Add Web Reference" is not going to work, and we need to take advantage of the hidden "Consume WCF Service" wizard, which comes as part of BizTalk 2006 R2. The wizard will generate required schemas, multi-part messages, orchestration port types, and also binding files for both basicHttp and custom binding. I'll put the steps here to consume a basic .asmx webservice in BizTalk 2006 R2 with WCF-BasicHttp adapter.

The sample webservice we are going to use contains a very simple webmethod as shown below.

[WebMethod]
public string ConcatName(string firstName, string lastName)
{
return firstName + " " + lastName;
}

The below walk-through is based on the sample webservice, which comes as part of the download.

  1. Create a blank BizTalk Project
  2. Right-Click on the project and select Add->Add Generated Items->Consume WCF Service
  3. Select the option "Metadata file (WSDL and XSD)", Click "Next"
  4. Open an instance of a browser and navigate to your ".asmx?WSDL" file and save it somewhere in your harddrive (Example: c:\Service.wsdl).
  5. Click on the "Add" button (next step in the wizard after the one shown above), browse to the .WSDL file you saved in Step 4, Click "Next" (Accept defaults), Click "Import" and then Click "Finish" to complete the wizard.
  6. Once you click "Finish" the following files will be added to your project (File name will depend on the name of the .WSDL file you selected)
    Service.BindingInfo.xml
    Service.odx
    Service_Custom.BindingInfo.xml
    Service.tempuri_org.xsd
  7. Open the Service.odx file, inside the orchestration view create 2 messages as shown below
    WSRequest - Multi-part Message Type - ConsumeWebService.ConcatNameSoapIn
    WSResponse - Multi-part Message Type - ConsumeWebService.ConcatNameSoapOut
  8. Right-Click on the orchestration "Port Surface", Click "Next", In the port properties page Click "Next", In the "Select a Port Type" page select "Use an existing Port Type" and select "ConsumeWebService.ServiceSoap", In port binding page select "I'll be sending a request and receiving a response." for port direction and "Specify later" for port binding. Click "Next" and then "Finish".
  9. Construct an orchestration as shown in the below figure
    Receive_1 -> Activate=true, Message= WSRequest
    Send_1 -> Message = WSRequest
    Receive_2 -> Message = WSResponse
    Send_2 -> Message = WSResponse
  10. I created a FILE Receive and FILE Send (Specify Now) port binding for port_2 and port_3
  11. Assign a key file to the project and set the "Application Name" to "ConsumeWebService". Build and Deploy the project.
    Open BizTalk Administration Console, Right-Click on the application and select "Import Binding". Browse to the auto generated binding file "Service.BindingInfo.xml" and select it.
  12. Bind your Orchestration to the correct ports and host. For the .asmx webservice logical port, select the auto generated "WcfSendPort_Service_ServiceSoap". (Start the application)
  13. Create a sample message by right-clicking on "Service_tempuri_org.xsd" file and clicking "Generate Instance". Drop the message in the folder you configured for port_2 in the orchestration, you should see the output result in folder you configured for port_3 in your orchestration.

Download the sample here

Nandri!

Saravana

Labels: ,




BizTalk 2006, WCF (basicHttpBinding), Adding Web Reference will go in end less loop.

Tuesday, May 29, 2007

When I tried to add a "Web Reference" to a WCF service (basicHttpBinding), I encountered following behaviors

1. Either it will throw an exception showing "Failed to add Web Reference" and no more clue anywhere, OR

2. Message saying "This page is accessing information that is not under its control. This poses a security risk. Do you want to continue?" it wont wait for your reply, it will go on endless loop until you click "NO" (then you need to close some 50 or windows), OR

3. It will throw an exception message saying, "Could not generate BizTalk files. Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index"

I attached following screen shots for reference:

(OR)

Tweaking the WCF config file with different setting didn't give me any luck. At last I figured out the issue is due to the namespace declaration for the WCF service. Just removing the namespace declaration and defaulting it to use "http://tempuri.org/" (which is not the best practice) solved the problem.

Before:

[ServiceContract(Name = "BackOfficeServices", Namespace = http://companyurl/Service/BackOffice)]

After:

[ServiceContract(Name = "BackOfficeServices"]

I can't really justify the reason, but I guess it will help someone.

Nandri!

Saravana

Labels: ,




Pipeline Component, XmlSerialization and Performance

I'm basically replying to Yossi's post here. I tried to leave it as a comment in his post but for some reasons my comments are not getting posted in his blog.

Myself and Yossi used to work together in a big public sector Healthcare BizTalk project for nearly 1.5 years.

First off all I need to thank Yossi for his complement about my white paper "Understanding Design-Time Properties for Custom Pipeline Components in BizTalk Server". Yossi mentioned in his post about the potential performance problem in using XmlSerializer inside pipeline component. Until now I thought his point is valid, but after reading the very first chapter from Professional BizTalk Server 2006 by (DJ, KS and EF) , where Darren explains about Serialization and performance hit, its clear there is NO PERFORMANCE HIT by using XmlSerialization in a BizTalk solution.

I thought the explanation will be helpful for readers to make the decision. The following extract is from the book (Page 11):

"When you first use the XmlSerializer in your application against a given type, a dynamic class is created and compiled on the fly to represent the serialized class. This has an obvious performance over head, but it will be cached for susbsequent requests

This cache is maintained per AppDomain, which is fine for applications like BizTalk, as there is by default only one AppDomain per BizTalk host.
"
.

So, eventually by using XmlSerialization inside the pipeline component, you'll hit the penalty only once during the lifetime of the component. That's until some one restarts the host.

Nandri!,
Saravana

Labels:




Create SQL Receive Locations Programmatically.

Friday, May 25, 2007

One of our recent projects involved creating an orchestration, which was bound to a physical one way receive port polling data from SQL server.  There will be multiple SQL receive locations for the same receive port. The receive locations will have different polling conditions based on the customer. Our requirement was to create one receive location per customer. So, we'll be adding more SQL receive locations as the customer base increases.  For that reason I created this function (part of a bigger client application) which create SQL receive location programmatically, which uses BizTalk Catalogue explorer object (no WMI). Hope this will be helpful to some one, because there is minor things to take care of.
 
You can download the .CS file from here.
 
The below figure shows a SQL receive location created with help of the above function.

How To Execute it:

Here is the sample code, which is used to run the function.

string server "SK_WORKSTATION";
string 
database "ORDER_POLLING";
string 
address "SQL://" + server + "/" + database + "/" + Guid.NewGuid().ToString();

CreateAndConfigureSQLReceiveLocation(
  
"Receive.SQL.Autogenerated.SK1"
"Receive.Sch.Orders.Internal.SQL.1Way.AllPollingService.ActivationMessages"
, address
"False"
"Minutes"
"10"
"DocumentRootElement"
"http://www.digitaldeposit.net/samples/SQL/schema"
"exec [GetSQLActivationMessage] @AccountNumber='007'"
"Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;User ID=sa;Initial Catalog=ORDER_POLLING;Data Source=SK_WORKSTATION"
"Data Source=(local);Initial Catalog=BiztalkMgmtDb;Integrated Security=true;Trusted_Connection=True"
);

NOTE: The function assumes you already got a "Receive Port" (which you pass as second argument to the function), but its not hard to create it inside the function.

Nandri!
Saravana

Labels:




Output custom formatted message from Orchestration.

Thursday, May 24, 2007

Have you ever wanted to create a custom formatted message. For example if you define a message of type System.String inside your orchestration and output it via an adapter the result will be as shown below

<?xml version="1.0" ?>
<string>Hello there</string>

this is because of the default serialization behavior of .NET base types within BizTalk. If in case you wanted to output the message as a simple string, in our case "Hello there" without any xml tags and processing instruction, you need to create your own .NET type with custom serialization and use it instead of System.String . In this post I'll explain how you can achieve this seamlessly with a similar sample by creating your own class with your own custom formatting serialization technique to create a sample email text message from an XML message. The sample solution contains full working sample and the code is self explanatory.

Orchestration:

We got a simple orchestration which takes an input XML message and produces the output in text format.

 

MSG_TEXT_EMAIL  is a message created from a custom .NET class called FormattedTextEmail.

The message assignment shape got the following one line code, which assigns a .NET type to the Orchestration XLang message MSG_TEXT_EMAIL.

MSG_TEXT_EMAIL = new FormattedEmail.FormattedTextEmail(MSG_XML_EMAIL.From, MSG_XML_EMAIL.To,MSG_XML_EMAIL.Subject, MSG_XML_EMAIL.Body);

As you can see there is no MAP's involved to do the transformation.

Input:

<ns0:EmailMessage xmlns:ns0="http://www.digitaldeposit.net/sample/schema">
  
<From>sk@email.com</From>
  
<To>gow@biz.com</To>
  
<Subject>Hey are you alrigh</Subject>
  
<Body>I found this sample really cool</Body>
</ns0:EmailMessage>

Output:

From : sk@email.com
To : gow@biz.com
Subject : Hey are you alrigh
Body : I found this sample really cool

Download Sample: CustomEmailFormat

Executing the sample:

1. Extract the solution to C:\BTSSamples

2. Open the visual studio solution, build and deploy it

3. Open BizTalk administration console, Open application "CustomEmailFormat",  Bind orchestration and Start the application

4. Drop the sample message inside the folder "C:\BTSSamples\CustomEmailFormat\FileDrop\In"

5. You should see the text output inside the folder "C:\BTSSamples\CustomEmailFormat\FileDrop\Out"

Related Reading:

http://msdn2.microsoft.com/en-us/library/bb418739.aspx

Nandri!

Saravana

Labels:




Can't see Debug statements in DebugView?

First of all to see debug statements inside DebugView you need to compile your assemblies in "Debug" mode. For optimization reasons if you compile your assemblies in "Release" mode all the System.Diagnostics.Debug.WriteLine statements will be ignored by the compiler and you won't see any output in the DebugView.

When it comes to BizTalk project sometimes even though the tool bar will say the build is "Debug" as shown in the figure

 

When you actually look into the properties of the BizTalk project it may be configured for "Deployment", which is equivalent to the "Release" build and it won't emit any debug symbols.

So, in this case you need to set the configuration to "Development", which is equivalent to "Debug" build.

Nandri!

Saravana

Labels:




BizTalk, MSDTC, SSO and Cluster

Monday, May 21, 2007

Last night (BTW it was a Sunday) around 8PM I received a call from my ex-boss and good friend Mike Prager who is working as a Senior architect in one of the major retail project in UK, saying "Hey! SK, we had a power failure this afternoon in our data center and after the servers came back all our receive locations are disabled and send ports are not started. When I try to access them via the admin console, I'm receiving the error

"Cannot retrieve list of objects due to a WMI provider failure"

have you experienced this before."

Well, I've seen this error in the past, but there are tons of things which can cause this error in BizTalk, we tried few things like checking whether all the SSO services are health on all the machines, MSDTC is running and configured correctly on each box, correct SSO master secret server is configured on the BizTalk group, etc, etc.

At last, I left Mike with the option to try DtcPing, since I'm not physically there. I couldn't assist much.

This morning I received a call from enthusiastic Mike, saying "Hey! I solved the problem, the error is due to the race condition (dependency) between the DTC and SSO service in the SQL cluster. When the SSO service starts before the DTC, there is an issue. You get the WMI error. But if the DTC starts before SSO, everything is well and good."

The reason I'm blogging it is I never experienced this before and it's one of those strange things which we'll never think about. I hope this will solve someone hours of troubleshooting time.

Thanks Mike, for sharing this information.

Nandri!

Saravana

Labels:




BizTalk Map - Suppress Element if Attribute is not required.

Friday, May 18, 2007

Scenario: The following question is taken from BizTalk.General NewsGroup (altered slightly for readability purpose)

"I'm mapping an element in the source schema to an attribute in the destination schema.  The element  does not exist in the source schema, but when I run the map it creates the element in the destination schema that houses the attribute I am mapping to.  The attribute does not show up in the result of the map, just the empty element. I need to have it not create the empty element if it is not going to put a value in the attribute."

Here is the solution:

Thanks goes to my collegue Matthew Johnstone and same technique was explained by Kiran Pabba in the newsgroup. I know for sure Matthew worked out this sample himself :-)

Labels:




BizTalk - Strange Exception Messages and Corresponding Fixes.

Thursday, May 17, 2007

During our BizTalk development we come across some really strange error message, which normally doesn't reflect the real cause. I always wanted to consolidate everything in one place. After seeing couple of errors that's being raised in the news groups, I thought this is the right time to materialize it. If you have come across any strange errors and willing to share please let me know via my contact page.

========================================================

Exception: 'System.Xml.XmlDocument' does not contain a definition for 'Status'

========================================================

Cause:

System.Diagnostics.Debug.WriteLine(PO_SOURCE.Status.ToString());

Resolution:

status = PO_SOURCE.Status;
System.Diagnostics.Debug.WriteLine(status.ToString());

where "status" is a variable of type System.String.

Credit: Tim

Remark: When you try to do the conversion directly on the context property, the above exception is raised. You can easily fix it by first assigning the context property to a local variable and then doing the conversion.

Date Logged: 17th May 2007 (BizTalk 2006)

========================================================

ERROR: The BAM deployment failed.
A connection cannot be made. Ensure that the server is running.
No connection could be made because the target machine actively refused it

========================================================

Credit: Saravana Kumar

Remark:

If you receive the following error when you try to deploy BAM activities using bm.exe tool

The error information doesn't reflect on the actual cause. Make sure, "SQL Server Analysis Services" is started.

Date Logged: 26th April 2007 (BizTalk 2006)

========================================================

A connection was successfully established with the server, but then an error occurred during the login process. (provider: Named Pipes Provider, error: 0 - No process is on the other end of the pipe.)

========================================================

Remark:

Make sure you Visual Studio project is pointing to the correct management server (Project Properties -> Deployment -> Server (BizTalk Group).

Date Logged: 29th May 2007 (BizTalk 2004/2006).

Nandri!

Saravana

Labels:




Orchestration - Handle SOAP Exception and deal with Suspended (resumable) messages

Wednesday, May 16, 2007

The main reason for this blog post is due to this newsgroup post

Download Sample from here.

Step #1: Catching SOAP Exception:

Whenever you call a Web service it's a good practice to handle the SOAP exception specifically rather than just leaving the orchestration to throw an un-handled exception which will result in orchestration service instance and all the referenced message instances being suspended. As shown in the following Orchestration diagram, handling a  SOAP exception is straight forward. Place your "Send" shape inside a "Scope" and add an Exception Handler with "Exception Object Type" configured to System.Web.Services.Protocols.SoapException (You need to add reference to "System.Web.Services"). The "Message Assignment" shape  inside the catch block got this simple statement

SOAP_EXCEPTION_MESSAGE = soapException.Detail.InnerXml;

Where SOAP_EXCEPTION_MESSAGE is an Orchestration message of type System.String and soapException is the "Exception object name" we assigned for the exception handler. So, with the following setup, whenever there is an exception a message similar to the one shown below will be generated and send across the wire with configured adapter (FILE, SMTP etc).

<string><ns0:NACK Type="NACK" xmlns:ns0="http://schema.microsoft.com/BizTalk/2003/NACKMessage.xsd"><NAckID>{2DA185D7-40E7-4279-9F6E-ADCEB6EF599B}</NAckID><ErrorCode>0xc0c01f07</ErrorCode><ErrorCategory>0</ErrorCategory><ErrorDescription>SoapException: System.Web.Services.Protocols.SoapException: Purposely raised this exception for testing at CustomerProcessing.Get500InternalSoapException(String yourName) </ErrorDescription></ns0:NACK></string>

Step #2: suspended(resumable) messages:

Even though you handled the SOAP exception using an exception handler in STEP #1, it's only going to complete the orchestration gracefully but it's going to leave the original request message you posted to the web services in a suspended(resumable) state. Bear in mind the SOAP exception will be raised inside the orchestration only after the send port has exhausted all the retries.  During this period the messaging instance and orchestration service instance will be in the dehydrated state as shown below.

After all the retries, the SOAP exception will be raised inside the orchestration and corresponding SOAP request message will be suspended with resumable state as shown below. This will help the administrator to either resume or terminate the message later.

 

But at some scenario we don't wont to leave the suspended (resumable) messages in the messagebox, instead move them to a different location (either to file system location or a remote server via HTTP etc, etc). Before BizTalk 2006 the only way to archive this behavior is by writing some WMI scripts, which is OK but doesn't really fit with the message flow infrastructure. But with BizTalk 2006 we can take advantage of "Failed Message routing" capability and make this task seamless.

All you have to do is, on your SOAP send port check the check box "Enable routing for failed messages" (as shown in the following figure) and also you can set optionally the "Retry Count" value to "0" if you want to raise the SOAP exception straight away.

Then configure a "Send Port"  (or an orchestration, if you want to do more business logic with the suspended messages) with following filter condition

ErrorReport.ErrorType == "FailedMessage"

ErrorReport.OutboundTransportLocation ==  http://localhost:47653/SOAPExceptionHandler.WebService/CustomerProcessing.asmx

The above filter condition will make sure you are dealing only with SOAP exception raised due to messages posted to that particular web service (CustomerProcessing.asmx). There are quite a bit of promoted properties that comes along with "ErrorReport" you can take advantage of to cater your situation as listed below.

  • Description
  • ErrorType
  • FailureCategory
  • FailureCode
  • InboundTransportLocation
  • MessageType
  • OutboundTransportLocation
  • ReceivePortName
  • RoutingFailureReportID
  • SendPortName

Related Reading:

http://blogs.conchango.com/matthall/archive/2005/07/28/1894.aspx

http://objectsharp.com/cs/blogs/matt/archive/2006/11/01/4110.aspx

Nandri!

Saravana 

Labels:




Data Tracking and Activity (DTA) Architecture

Tuesday, May 15, 2007

The following picture will tell you all about the DTA architecture in BizTalk server

I came across this picture in MSDN (http://msdn2.microsoft.com/en-us/library/aa559554.aspx) , very simple and elegant explanation of DTA architecture. I thought it's worth keeping it for reference. Visit the above link for details about each step.

Nandri!

Saravana Kumar

Labels:




Are you going to create new schema (.xsd file) from existing one? Here is the quick tip for BizTalk beginners.

Step #1: Within Visual Studio copy the schema (.xsd file) and Paste it. Rename the file to appropriate name.

Step #2: Click on the <Schema> node and change the "Target Namespace" property in the properties window as shown below. (NOTE: This step is required only if you want to change the target namespace, else you can ignore and go to Step #3)

Step #3: Click on the Root node and change "Node Name" property in the properties window as shown below. Changing the "Node Name" property will automatically change "RootNode TypeName". Make sure they are the same.

Step #4: Click on the .xsd file in the solution explorer and click F4 (or make sure the properties window is visible, when you select the .xsd file). Set Appropriate name (usually the root node of your schema) to the "Type Name" as shown in the below figure. This is crucial, since all the schemas contained inside the project will be compiled into typed objects, derived from corresponding BizTalk artifact classes. (Example: If you look at the compiled "dll" of this sample project,  using Reflector, the class definition will be public sealed class PO_Target : SchemaBase).

That's all, your new schema is ready to be used now. Apart from all the properties windows we have seen there is one more property window for the schemas (can be seen by right clicking on the .xsd file and selecting "Properties" from the context menu) as shown in the below figure

You configure things like "Output Instance filename" which will be used when you generate a sample file from schema, "Input Instance file" which will be used when you want to validate a message against a schema etc.

Nandri!

Saravana 

Labels:




Detect CLR version under which your BizTalk service is running.

Saturday, May 12, 2007

It's becoming more and more eminent to understand under which CLR version (1.0, 1.1 or 2.0) the BizTalk runtime, In-Process host is running. I've explained in my previous post the various factors that influence loading appropriate CLR versions and also how you can make use of the config file to force a specific version of CLR is always loaded.

There is one more query raised, what happens if you install .NET Framework 3.0 on your BizTalk server (both 2004 and 2006)? The effect of installing .NET 3.0 doesn't introduce that much behavior difference when compared to installing .NET 2.0 on a BizTalk 2004 machine (built using .NET 1.1 with CLR 1.0). Because .NET 3.0 is still based on .NET 2.0 and shares the same compilers and Common Language Runtime (CLR 2.0). See the following posts from Somasegar and Jason Zanders (comments are more interesting on the both the posts)to see the effect of .NET 3.0.

With all this confusions around different versions of .NET and different versions of BizTalk and different Service Packs, there will certainly be a situation where developers and administrators need to figure out the version of CLR under which the BizTalk Runtime is running. This is where Process Explorer comes to our rescue.

Process explorer's top window shows a list of currently active processes, and the bottom windows shows either the handles opened by the selected  process or it shows the DLL's and memory mapped files that the selected process has loaded. You need to set the appropriate mode from the menu item "View-> Lower Pane View". In our case we need to figure out the version of Common Language Runtime core dll (mscorwks.dll) loaded into the BizTalk runtime process (BtsNtSvc.exe). So, we'll set the "Lower Pane View" to DLL's (or Ctrl + D).

Also, make sure the following columns are visible Description, Image Path, and Version. To do so, click on "View" menu and select "Select Columns" and in the "Process Image" tab select appropriate columns.

 The following screen shot is taken from a machine running BizTalk 2006. You can see clearly from the bottom pane the version of CLR running is 2.0 and physical dll is loaded from the location "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll". BTW, .NET 3.0 is installed in this particular machine, which also proves .NET 3.0 still uses CLR 2.0. In BizTalk 2006 box its quite straight forward it's all .NET 2.0. Things will become more interesting in BizTalk 2004 scenario.

Nandri!

Saravana

Labels:




BizTalk 2004 and .NET 2.0

Tuesday, May 08, 2007

Under which version of .NET Framework my code is going to run?
I came across this interesting question in BizTalk newsgroup, "I am just wondering though how my local computer knows which CLR to load for the BizTalk Server 2004 Orchestrations when there is no entry in the BTSNTSvc.exe.config file to specifically point to the .NET 1.1 Framework when .NET 1.1 and 2.0 Frameworks are loaded to my computer. ".

Here is my explanation:

Applications that do not carry a configuration file or at least the supportedRuntime element in their configuration files (unconfigured applications) execute with the version of the framework that was used to build the application, provided that version of the Framework is installed on the local system. The version of the Framework with which the application was built is contained in the header (MANIFEST) of the application (assembly). Executing the following line of code against  Microsoft.XLANGs.BizTalk.Engine.dll in a BizTalk 2004 environment will output the result as v1.1.4322. The same piece of code in BizTalk 2006 environment will output v2.0.50727.

Console.WriteLine(System.Reflection.Assembly.LoadFile(@"C:\Program Files\ Microsoft BizTalk Server 2006\ Microsoft.XLANGs.BizTalk.Engine.dll").ImageRuntimeVersion);

There are two important things which drives what version of framework will be used at runtime :
1. When the expected version of the Framework is not available, the CLR uses a later version of the Framework in its place. In other words, an unconfigured assembly built with Framework 1.1 executes with 1.1 on a system that has both 1.1 and 2.0 installed. That same assembly executes with the 2.0 Framework on a system with only the 2.0 Framework installed.
2. When it comes to interop scenarios the default behavior of CLR is to load the latest framework. This is because unless the managed assemblies, unmanaged assemblies lack the information in their header that describes the version of the framework (as we seen with the code snippet earlier) the code in question was build with; this leaves the CLR with no choice other than to load the latest available version of the framework.

Some of the assemblies used by BizTalk (both 2004 and 2006) runtime components falls under the second category (interop assemblies), which leaves CLR to load the latest available framework.  If you need to override these default behavior, you can set the supportedRuntime/requiredRunTime in the .config file (BtsNtSvc.exe.config for In-Process host and corresponding IIS config file based on version 5.0 or 6.0 either dllhost.exe.config or w3wp.exe.config for isolated host)  for the process as shown below, which forces to use .NET framework 1.1.

<configuration>

<startup>
<supportedRuntime version="v1.1.4322" />
</startup>

</configuration>

Ultimately, this means all managed components called by a particular application (BizTalk 2004) runs on the same version of the Framework.

New Assembly, Old .NET

It's advisable to build your custom assemblies against the same version of .NET that you will be running them against. i.e .NET 1.1 for BizTalk 2004 and .NET 2.0 for BizTalk 2006. That way you'll have correct references and avoid surprises from behavior difference between builds.

Custom components that are written to use the .NET Framework 2.0 will not work in BizTalk Server 2004. These components include adaptors, pipeline components, functoids, and user code that may be referenced from orchestration or rules policies. This is because new assemblies cannot be opened on older CLR, just because they don't understand them, and the runtime will throw BadImageFormatException.

References:

http://support.microsoft.com/kb/841405

http://blogs.msdn.com/suzcook/archive/2003/06/20/57191.aspx

http://blogs.msdn.com/suzcook/archive/2005/01/26/new-assembly-old-net-and-vice-versa.aspx

http://msdn2.microsoft.com/en-us/library/ms994410.aspx

Nandri!

Saravana

Labels:




Ah!! Control flow didn't get into my exception handler block inside the orchestration (or) how can I handle the exception when the send port raises the error with suspended (resumable) status.

Thursday, April 26, 2007

Conditions:

1. Above orchestration is constructed with just default settings.

2. Logical port Port_2 is configured to use a Send Port with FILE adapter pointing to an unknown URI (purposely, to generate error) and RetryCount = 0

3. Logical port Port_5 is configured to use a Send Port with FILE adapter (normal valid setting).

Will the control flow get into exception handler?

In the above scenario the orchestration will complete successfully without throwing any exception even though the message is not transmitted successfully to the target recipient. The main reason for that is because the orchestration engine successfully persisted the message and state into the MessageBox database. So, from Orchestration perspective the transaction was successful.  But, when the send port picked up the message, it couldn't transmit the message successfully due to the KNOWN URI configured in the FILE adapter, so it raised an exception and suspends the referenced message with Suspended (resumable) status. Later an adminstrator can correct the configuration in the send port with correct URI and resume the message from admin console, which then will transmit successfully.

The end result is the control flow didn't get into the exception block, even though logically there is an exception in the transmission.

So, how can I make the control flow to get into my exception block:

I made few changes to the Orchestration:

1. I set the "Delivery Transmitted" property to "Transmitted" for Port_2

2. Changed the exception handlers, "Exception Object Type" to "Microsoft.XLANGs.BaseTypes.DeliveryFailureException"

3. Created a new message using Orchestration View called EXC_MESSAGE (just System.String type), and modified the exception handler block as shown in the following figure, added a construct shape with follwing statements inside MessageAssignment

soapExc = (System.Web.Services.Protocols.SoapException)delFailException.InnerException;
EXC_MESSAGE = soapExc.Detail.InnerXml;

where, delFailedException is the name of the catch exception block,  soapExc is a local variable of type SoapException.

Now,  the message flow will get into the exception handler block and following ERROR message will be transmitted via the Send shape (eventually to the configured physical send port) configured in the exception handler.

<?xml version="1.0" ?><string><ns0:NACK Type="NACK" xmlns:ns0="http://schema.microsoft.com/BizTalk/2003/NACKMessage.xsd"><NAckID>{8F3626A6-E110-49AF-802A-8E85BD5016C6}</NAckID><ErrorCode>0xc0c01c10</ErrorCode><ErrorCategory>0</ErrorCategory><ErrorDescription>The FILE send adapter cannot open file C:\BTSSamples\Listen Timeout Exception\File Drop3\02. OUT RES\{66A1BABF-5509-42CE-82F8-0E100852C526}.xml for writing. Details: The system cannot find the path specified. </ErrorDescription></ns0:NACK></string>

You can do lot of things with this error message now, like for example: you can email it to the adminstrator.

Summary:

So, there is nothing new here "Delivery Notificaition" and "NACK" messages are been there for a very long time. The reason for this post is a result of 2 questions raised in the newsgroup

1. My Control flow is not passing to the exception handler, and

2. How to handle Suspended (resumable) exceptions within orchestration.

Nandri!

Saravana

Labels:




BizTalk - Strange Exception Messages and Corresponding Fixes.

During our BizTalk development we come across some really strange error message, which normally doesn't reflect the real cause. I always wanted to consolidate everything in one place. After seeing couple of errors that's being raised in the news groups, I thought this is the right time to materialise it. If you have come across any strange errors and willing to share please let me know via my contact page.

==========================================================================

Exception: 'System.Xml.XmlDocument' does not contain a definition for 'Status'

==========================================================================

Cause:

System.Diagnostics.Debug.WriteLine(PO_SOURCE.Status.ToString());

Resolution:

status = PO_SOURCE.Status;
System.Diagnostics.Debug.WriteLine(status.ToString());

where "status" is a variable of type System.String.

Credit: Tim

Remark: When you try to do the conversion directly on the context property, the above exception is raised. You can easily fix it by first assigning the context property to a local variable and then doing the conversion.

DateLogged: 17th May 2007 (BizTalk 2006)

==========================================================================

ERROR: The BAM deployment failed.
A connection cannot be made. Ensure that the server is running.
No connection could be made because the target machine actively refused it

==========================================================================

Credit: Saravana Kumar

Remark:

If you receive the following error when you try to deploy BAM activities using bm.exe tool

The error information doesn't reflect on the actual cause. Make sure, "SQL Server Analysis Services" is started.

DateLogged: 26th April 2007 (BizTalk 2006)

Nandri!

Saravana

Labels:




More on Internet Service Bus (BizTalk Services)

There are more confusion around people regarding BizTalk Services (Identity, Connectivity, ServiceBus, and Workflow). Why do we need all this additional service? Is there any business value? Will it make any difference to my client. etc etc

Of course it will, remember the services are just in CTP, the more it get matures companies will come up with more ideas. Clemen Vasters from connected system division got an excellent post about "BizTalk Services" and the practical requirement for such services.

Extract from his post:

"If you are an ISV catering shrink-wrapped business solutions to SMEs whose network infrastructure may be as simple as a DSL line (with dynamic IP) that goes into a (wireless) hub and is as locked down as it possibly can be by the local networking company that services them, we can do as much as we want as an industry in trying to make inter-company B2B work and expand it to SMEs; your customers just aren't playing in that game if they can't get over these basic connectivity hurdles."

Related Links from this blog:
BizTalk Services. How does Identity Service and Connectivity service fit together.
BizTalk in the direction of SaaS (Software as a Service)


Nandri!
Saravana

Labels:




BizTalk Services. How does Identity Service and Connectivity service fit together.

Wednesday, April 25, 2007

From my understanding of BizTalk Services (Identity, Connectivity, ServiceBus, and Workflow) so far, the word BizTalk doesn't really mean much(at least at the moment, with currently live Identity and Connectivity (aka Relay) services). May be it will make sense once  ServiceBus is live. There is nothing offensive here.It makes sense more on Windows Communication Foundation (WCF) front rather than BizTalk.

What is Identity Service?

Identity service is a way of authenticating end users and connected systems. Much similar (but not the same) to Microsoft's effort of introducing Microsoft Passport few years back,  as one stop shop for your authentication needs.  Identity services (previously called Secure Token Services - STS) uses Windows Cardspace technology to authenticate clients (both users and connected systems) using claims based access control. To use any other services like Connectivity, the authentication needs to be performed via Identity Service. So, it's mandatory to create an Identity Service account (Create New Account). On client side IE 7.0  is required.

What is Connectivity Service?

Connectivity Service is also called as Relay Service, which provides two main functionality:

1. Ability to create a listening endpoint (WCF endpoint) at the relay service, and

2. Ability to Send and Receive messages to and from that endpoint.

Listening endpoint is created by, configuring an application to listen on a public address (ex: net.relay://connect.biztalk.net/services/SARAVANA_W2003/HelloWorld/). If that address is available and the user is authorized, the relay service will start listening on that address on behalf of the application. The following config code snippet shows, how you'll create a listening endpoint on a relay service from your WCF service application.

<service name="Saravana.DigitalDeposit.HelloWorld">
<endpoint name="RelayEndpoint"
contract="Saravana.DigitalDeposit.HelloWorldContract"
binding="relayBinding"
bindingConfiguration="default"
address="net.relay://connect.biztalk.net/services/SARAVANA_W2003/HelloWorld/" />
</service>

Microsoft has build some specific WCF bindings called Relay Bindings, to make integration seamless with Relay Service.

How Identity Service and Connectivity service fit together:

The following figure shows the high level overview of how both the services (Identity and Connectivity) work together.

Server Authentication and establishing a Listening endpoint:
Step #1: An application behind a firewall (Example: HelloWorld Service) requests a security token for the Relay Service from the Identity Service.

Step #2: Identity Service responds with the appropriate token (assuming that "HelloWorld Service" could successfully authenticate to the service).

Step #3: "HelloWorld Service" initiates a connection to the Relay Service and asks to listen on a particular address (Ex: net.relay://connect.biztalk.net/services/SARAVANA_W2003/HelloWorld/). If the address is available and "HelloWorld Service" is authorized, a listening endpoint is created.

Client Authentication:
Step #4: The Client application requests a security token for the Relay Service from the Identity Service.

Step #5: Identity Service responds with the appropriate token (assuming the Client could successfully authenticate).

Sending and Receiving Messages:
Step #6: The Client formulates the application message and sends it to "HelloWorld Service" address on the Relay Service (Ex: net.relay://connect.biztalk.net/services/SARAVANA_W2003/HelloWorld/). The Client includes the security token it received in Step #5.

Step #7: The Relay Service forwards the application message down the open TCP connection to "HelloWorld Service".

Step #8: "HelloWorld Service" creates an application response and sends it back to the Relay Service.

Step #9: The Relay Service completes the outstanding HTTP request with an HTTP response containing the application response message.

Hope this gives a basic understanding of Identity and Connectivity services.  The documentation at the moment is very thin, I'll recommend downloading the SDK, which got some good sample to start with.

Nandri!

Saravana

Labels:




BizTalk Server 2006 R2 Support Forum, How to get hold of WCF LOB Adapter SDK.

Tuesday, April 24, 2007

I haven't seen people highlighting about the BizTalk Server 2006 R2 forum in the blogs. If in case you haven't come across, there is a separate forum to post questions related to BizTalk Server 2006 R2.  The forum is categorized into following sections:

 

In one of the forum post Sonu Arrora (Program manager, WCF LOB Adapter SDK) explained how you can get hold of the WCF LOB Adapter SDK, which doesn't come as part of default install.

  1. Visit the following link and login using your .NET passport account https://connect.microsoft.com/Downloads/Downloads.aspx?SiteID=65
  2. Select the package named "BizTalk Adapter Pack and WCF LOB Adapter SDK";

IMPORTANT: Adapter SDK Beta 2 is not a public beta yet.  You need to contact btsr2tap@microsoft.com to get access to the Adapter SDK Beta 2 bits.   They can grant your passport account access, under some beta software evaluation license agreement.

UPDATE: Unfortunately WCF LOB Adapter SDK is not for everyone until Q3, I received the following email from MS

Saravana,

The ASDK is currently only available to TAP customers. The ASDK will be publically available in Q3.

Thanks.
James Snow
TAP Program Manager

Nandri!

Saravana

Labels:




BizTalk in the direction of SaaS (Software as a Service)

I heard the announcement of "BizTalk Internet Services" from Connected Systems Division in Microsoft through BizTalk server team blog.

What is SaaS?
Software as a service (Saas) is an application delivery model where vendors develop applications and hosts and operates the application for use by its customers over the internet. SaaS vendors typically utilize a "multi-tenant architecture", meaning that multiple customers are running the same software, but with a virtually separate data. SaaS was originally considered a potential security and operational risk. Many businesses wish to keep their information technology operations under internal control. However, there is a counter-argument that the professionals operating SaaS applications may have much better security and redundancy tools available to them, and therefore the level of service may be superior in many cases.

Example: Google Apps, a classic example, where they made their gmail services as a hosted service for companies to utilize, without the burden of setting up their own environment.

There is clear hint from BizTalk Server Team message, the service won't be free:

"Also, given the early stage, these services are available for free which may change down the road".

Initial release of BizTalk Internet Services include (as of 24th April 2007):

  • Message routing - firewall friendly B2B messaging (Available now)
  • Simple publish/subscribe event brokering - Pub/Sub at Internet scale (Coming soon)
  • Simple federated identity and access control (Available now)
  • Workflow processes - Simple templates for cross-organization integration and the orchestration of business processes interacting with multiple services (Coming soon)


When I tried to access http://labs.biztalk.net/, it asked for User Name and Password. As of now I don't know how you can participate in the program, even though the message from BizTalk Server team clearly states

"We are inviting developers from all over the world to use the services and provide feedback. Our vision for services, much like our vision for software, is to radically improve the productivity of developers as they build next generation applications."

I'll update this post, once I get the answer.

UPDATE #1 (23rd Arpil 2007):

1. There is an article in eWeek (April 23, 2007) explaining more about this.

2. Developers who want to get hold of this service now, there is an excellent post by Dennis, explaining step by step, procedure you can follow to kick start.

3. You can download the SDK for Relay and Identity service.

Thanks Bernabe for pointing the link.

UPDATE #2 (25th April 2007):

1. More about BizTalk Services in eWeek (not the same article mentioned earlier)

2. Good write up by Steven Martin in this post

Thanks Richard for pointing the links.

Update #3 (27th April 2007):

Steve Forte explain how BizTalk services will help his company Corzen outsource its spidering needs

http://www.stephenforte.net/owdasblog/PermaLink.aspx?guid=a8de9324-c373-4cab-8e10-4e23251a3fb4
Nandri!
Saravana

Labels:




Configure your BizTalk applications to run under seperate Host with Click of a button?

Thursday, April 19, 2007

UPDATE: Full source code of this project is now available at CodePlex. Project URL http://www.codeplex.com/BizTalkAppHostConfig

Companies use BizTalk Server in a variety of configurations. Let's see this scenario:

Scenario: Company-X is a medium sized company they got variety of small BizTalk applications like "Order Processing", "Payroll Processing", "Payment Processing" etc. But they only have one BizTalk infrastructure (they got replica setting for testing and production) with 2 BizTalk application servers (BizTalk group) connected to 2 SQL servers clustered. All their BizTalk applications are deployed in this BizTalk group. All the applications are configured to run within the default In-Process and Isolated host and one instance per host is created on both the application servers.

The main issues with the above scenario are:

  • Every time a new application is deployed or existing application is upgraded the host instances needs to be restarted (to refresh cached components). Stopping or restarting the host instance is going to affect each and every deployed application. At the minimum none of the applications are going to process any messages during the upgrade process.
  • Security can be compromised, because there is no security boundary between applications.
  • If one application causes problem to the host instance it's going to affect the overall system.

The solution to the above mentioned problems is to create separate logical hosts for each application and then creating corresponding host instances. Logical hosts can be created for BizTalk application using variety of tools that comes out of the box like BizTalk administration console, WMI, etc, but we'll face the following issues

  1. A thorough understanding of the host and host instances concept is required for the person who is performing the task.
  2. Creating logical host and configuring the BizTalk artifacts manually (handlers, receive locations, send ports and orchestrations) are error prone.
  3. Managing multiple logical hosts and their corresponding configuration will become more difficult over time.

ApplicationHostCreator is designed to create and manage logical hosts for BizTalk applications seamlessly to support situations as described in the above scenario.

Read more about how to use the tool and download version 1.0 of the tool at http://www.biztalk247.com

LINK: http://www.biztalk247.com/v1/articles/appHostCreator.aspx

Nandri!

Saravana

Labels:




Can you use Dynamic Send Port without Orchestration? Yes you can.

Dynamic send ports are used in situations, where you don't know in advance the type of transport adapter to use to send messages to your trading partner. May be based on certain content in your message you need to make that decision at runtime to pick up the transport adapter. The below figure shows the configuration for a Dynamic One-Way Send port, you can see you only specify the Name and Pipeline details (you can specify some of the other properties like maps, filters, etc).

Example Scenario: Say you are receiving an order message as shown below, which contains the "From" and "To" information in the header.
<Order>
<Header>
<From>me</From>
<To>Contoso</To>
</Header>

<Body>.........</Body>
</Order>

Based on the "To" (trading partner name) you need to pick up the appropriate transport (ex: Contoso = FTP, Northwind=HTTP).

Dynamic Send port works very well with Orchestration, all you need to do is specify the following line inside your expression shape

Port_1(Microsoft.XLANGs.BaseTypes.Address) = "http://www.tradingpartner.com/receive.ashx"

That's all it requires to route the message to dynamic send port. BizTalk resolves the correct transport address from the URI you specified.

(I put the following screen shot, so you know what I'm talking about) 

Behind the Scene:

When you create a Dynamic Send Port from BizTalk management console and start it, in the background BizTalk creates subscriptions for all the adapters installed in your server. A query for subscription shows the following result.

If you look at the expression used inside the subscription you'll see it's looking for 3 properties "OutboundTransportType" (HTTP,FILE,FTP etc), "SPID" (Send Port Id) and existence of "OutboundTransportLocation". The below figure shows the expression used for SendPort4: HTTP

When the orchestration submits the message to the MessageBox it promotes these three properties in the message context, which then gets picked up by the corresponding Dynamic Send Port.

How to use Dynamic Send Port without Orchestration?

If you want to use Dynamic Send Port in a  content based routing scenario (aka Messaging-Only scenario) one option is to promote the 3 properties

  • OutboundTransportType
  • SPID
  • OutboundTransportLocation

somewhere in your receive pipeline using custom pipeline component and submit it to the message box, which will then be picked up by the corresponding Dynamic Send Port. The only problem with this approach is SPID (Send Port id) is a system generated value and it might differ from environment to environment.

So, what's the best solution?

All you need to do is define a new FILTER in your Dynamic send port, example BTS.ReceivePortName == <<your receive port name>>. That's all it requires. Now if you look at the expression for SendPort4: HTTP you can see it accepts 2 different conditions one with SPID OR the other other one with ReceivePortName. So, all you need to do now is promote the following properties somewhere in your receive pipeline and submit the message to the MessageBox.

  • ReceivePortName
  • OutboundTransportType
  • OutboundTransportLocation

Instead of ReceivePortName you can use whatever promoted property you have in your system. Now, you know for sure those values are not going to change like SPID.

Nandri!

Saravana

Labels:




BizTalk HotRod Magazine.

Tuesday, April 17, 2007

This morning I came across this interesting magazine via Richard Seroter. I quickly glimpsed through the magazine at work and was very impressed by the contents straight away.

 This is the first magazine I've seen dedicated to BizTalk resources. The first issue contains 8 good articles written by people from Microsoft and its partners.

After seeing the content of the magazine I couldn't resist to wait till the weekend to update  BizTalk247. So, I added a new section to BizTalk247 called MAGAZINE which previews the content of BizTalk HotRod.

I encourage all BizTalk developers to go through the articles in the magazine they are well written based on real time customer situations.

As a feature article, there is an article from Stephen Kaufman which highlights the features of BizTalk 2006 R2.

Nandri!

Saravana

Labels:




Passed 70-235. Here is my Exam Preparation Diary.

Wednesday, March 07, 2007

TS: Developing Business Process and Integration Solutions Using Microsoft BizTalk Server 2006 was in my TODO list for a very long time. My last exam  was 74-135 BizTalk 2004 Exam way back in April 2005.

So I decided to write the exam on 5th of March 2007. I did some search to gather as much information as I can to prepare for the exam. For this exam I need to pull materials from variety of sources like MSDN, Blogs, WebCasts, Books, MS e-Learning and Product documentation. It took me enormous amount of time and effort to gather all the materials than actually preparing for the exam. I remember doing the same thing for my 74-135 BizTalk 2004 Exam, now I need to start everything again. So, this time I decided to document each and every step I move forward towards the exam goal and here is the outcome BizTalk Server 2006 Exam (70-235) Preparation Diary

As my first article after the launch of BizTalk 24 * 7 I've published my exam preparation diary, hoping it will be helpful for people not only taking the exam but also for some one preparing for interview, or in general a good reference, where all the important points related to BizTalk is in one place. It will be helpful for experienced BizTalk pe