Monday, January 21, 2008

BizTalk Context Property Class Generator - BTSPscGen.exe

When working with BizTalk Pipeline components, it’s a common requirement to work with context property values.

The context property key is actually XML element defined in the Property Schema, and is a combination of the name and namespace of the XML element.

To read a context property value, you use the Read method on the context object of IBaseMessage:

object Read(string strName, string strNamespace);


Now, because its so easy to make mistakes with the name and namespace (just like all other string value in your code) its very advisable to save those values as constants. Something like that:

const string EPMRRCORRELATIONTOKEN_NAME = "EpmRRCorrelationToken";

const string EPMRRCORRELATIONTOKEN_NAMESPACE = "http://schemas.microsoft.com/BizTalk/2003/system-properties";


public IBaseMessage Execute(IPipelineContext context, IBaseMessage inMsg)

{

object epmObj = inMsg.Context.Read(EPMRRCORRELATIONTOKEN_NAME, EPMRRCORRELATIONTOKEN_NAMESPACE)


if (epm != null)

{

//Do Something here

}

return outMsg;

}


More elegant way is to use the classes in Microsoft.BizTalk.GlobalPropertySchemas.dll


public IBaseMessage Execute(IPipelineContext context, IBaseMessage inMsg)

{

BTS.EpmRRCorrelationToken epm = new BTS.EpmRRCorrelationToken();

object epmObj = inMsg.Context.Read(epm.Name.Name, epm.Name.Namespace);

if (epm != null)

{

//Do Something here

}

}


You can see the benefits of the second approach with Reflector:

Property schema element class


  • The class has Type property that is the CLR object type of the context property value.
  • System.Xml.XmlQualifiedName object (that have some useful method itself) include the name and namespace values.

To me it's seemes that the above is the most appropriate way, so, if you want to create your own GlobalPropertySchemas.dll follow thoes steps:

  1. Create a new BizTalk project
  2. Create a folder with the appropriate Name (ex. ESB)
  3. Add a new property schema (ex. ESBProperties)
  4. Add the context-properties (ex. ServiceName).
  5. complie

the results are generated classes for each context-property (ex. ESB.ServiceName)

For educational proposes, I once wrote a utility that takes a user defined BizTalk schema property and generates this class for every element so you could see what happens behind scene. also, you can extend this tool and create more "smart" classes for your own GlobalPropertySchemas.dll

So, go ahead and start using your own GlobalPropertySchemas.dll in the very same way that BizTalk artifacts are using property schema elements from inside code.

BTSPscGen.exe source-code can be download form: http://pinhask.googlepages.com/BTSProperySchemaClassGen_Source.rar

Enjoy!.

Sunday, January 20, 2008

BizTalk Host instance and Windows NT Services limit issue

When developing SOA/ESB solutions, you should NOT use the same Host instance for more then one service. the reason is because all messages will be writen into the same table (queue), so if one service is consumed intensively, the other services will experience latency.

To avoid this, it's a known best-practice with BizTalk solutions, to create at least 3 Hosts instances per service:

  • Orchestrations Host
  • Receive Ports Handler
  • Send Handler

An important and little known issue is the limit number of host instances that can be defined on a single machine.

Every host instance in BizTalk is implemented as a Window NT Service with the prefix 'BizTalk Service BizTalk Group : 'HostName'.

Now, services can run under one of two Accounts:

  • User Account
  • LocalSystem

Windows can host unlimited number of services running under LocalSystem, but By Default, has a limit number of services running under User Account (from my experience with Windows 2003 Server it's between 23 to 25, based on the service memory usage).

If you reach this limit, the host instance won't start and you'll get the following error massage:

1053 The service failed to start due to the following error: The service did not respond to the start or control request in a timely fashion.

The only solution is to decrease the memory for each desktop on the computer.

In the following I'll show you how to set this key in the system registery:

Run regedit.exe and browse to:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems\Windows

Find the key 'SharedSection=1024,3072,512'

The third value (512) is the desktop heap for each desktop that is associated with a "noninteractive" window station. this value can be decreased down to 128.

More information can be found on
http://support.microsoft.com/kb/184802/en-us (cause 2).

Very important:

Please DON’T do this on production environment before a VERY CARFUL test – this key can affected and harm the system very badly. So please check if it suitable for your system before running and applying it.

Saturday, January 12, 2008

The ESB Guidance – hello ‘SOA’ world

Introduction to BizTalk solutions architectures.

Almost all IT professionals are familiar with the benefits Service Oriented Architecture (‘SOA’) approach is offering, therefore the term ‘ESB’ is not a buzz word any more.

As a BizTalk developer the architecture you often use is known as ‘Hub-And-Spoke’. This means we’re using BizTalk as a middleware application (known as a ‘Broker’) between of all other applications. When app A needs to interact with app B, it will submit the request to the broker application. The broker then will make the preparations needed to redirect the request to app B (one example is transformation) and then route the message into app B and vice versa.

Enterprise Service Bus ('ESB') extend of the traditional EAI and MOM broker with some capabilities like:

  • Web Service standards
  • Integration with rang of protocols and technologies.
  • metadata registry

As a rule of thumb, ESB is the gate into the ‘SOA’ world.

It means you don’t develop ‘Application’ anymore; from now on it is about ‘Services’.

If you’re new with ‘SOA’ you can learn about it here.
Also, you can find an overview of BizTalk Server based 'ESB' here.

Now, because of BizTalk ‘Hub-And-Spoke’ nature, developing ESB solution based on BizTalk Server require massive development of infrastructures, The ESB guidance is Microsoft way of achieving it in the fastest way by integrating and relaying on common Microsoft technologies.

Sunday, January 6, 2008

Microsoft ESB Guidance is here

Microsoft finally released the toolkit for developing ESB solutions based on BizTalk Server.
if you're a BizTalk developer and 'ESB' is your second name [the first one is probably 'SOA' :-) ] this set of powerful tools was designed exactly for you. It can make your life match more happier and save you a lot of coding time.

you can find the ESB Guidance on the MSDN Here

In the next few posts I'll give you a deep dive into this new exciting tools and framework.

Wednesday, January 2, 2008

BTS 2006 Soap Adapter XmlSerializer Bug ?

In one of the projects my team recently worked on, we notice a mysteries behavior of the Soap Adapter. We had to consume a web service that contains some value-type elements.

When I looked into the WSDL file, I've notice that each element contains two attributes:

  • minOccurs="0" - you can simply drop the element from your input
  • nill="True" - you can pass null value for this element.

Now, in general, the combination of xsi:nill=True" and minOccurs="0" doesn't make match sense because you don't need to pass null value if you can just drop the whole element - But, this was the case.

I added the Web reference and happily deployed my project.

The service refused to work. so, after investigation and some little sniffing (I just LOVE WireShark...) I realized that all of the nullable value-typed elements are missing.

It's odd because when I saved the tracking messages directly from the HAT, all of them appeared in the output xml.

BizTalk is saying 'A' but WireShark was showing 'B' - where was the problem?

To figure it, Lets consume some web service from a simple C# console application. The WSDL contains a complex type with the name "MyClass". the class has two value-type member. one of them (SomeNullableInt) is configured as nillable="true"

<s:complexType name="MyClass">
  <s:sequence>
    <s:element minOccurs="0" name="SomeInt" type="s:int" />
    <s:element minOccurs="0" name="SomeNullableInt"nillable="true" type="s:int"/>
  </s:sequence>
 </s:complexType>
 
Now, add the web reference to your project and see that in the auto-generated proxy class, the "SomeNullableInt" member declared as Nullable<T> type:

[Serializable()]
public partial class MyClass
{
       public int SomeInt {...}

       [XmlElement(IsNullable=true)]
       public System.Nullable<int> SomeNullableInt {...}
}
 
Next, create an instance of MyClass object and init the members with values. then serialize the object into XmlDocument and write the OuterXml to the Console window.

static void Main(string[] args)
{
    MyClass myClass = new MyClass();
    myClass.SomeInt = 1234;
    myClass.SomeNullableInt = 1234;

    myClass.SomeIntSpecified = true;
 
    XmlDocument doc = new XmlDocument();
     MemoryStream ms = new MemoryStream();
     XmlSerializer s = new XmlSerializer(typeof(MyClass));

     s.Serialize(ms, myClass);
     ms.Seek(0, SeekOrigin.Begin);
    doc.Load(ms);

    Console.WriteLine(doc.OuterXml);
    Console.ReadLine();
}

So, As you can see, the Nullable<T> member is ignored in the serializing process.It's look like the default .Net System.Xml.Serialization.XmlSerializer can't serialize Nullable<T> Type.

The actual reason to this behavior is because of the minOccurs="0" attribute. this means that the element doesn't have to occur in the xml document, the XmlSerialization mechanism checking the element using the '<elementName>Specified' Property generated with the proxy class. it's seems like the proxy generator doesn't checking this property for Nullable<T> types, maybe becouase you would expect the XmlSerialization engine to be smart enough to use the 'HasValue' property of the Nullable<T> class to get this information.

So let's change the Wsdl to be like this:

<s:complexType name="MyClass">
<s:sequence>

    <s:element minOccurs="0" name="SomeInt" type="s:long" />
    <s:element name="SomeNullableInt" nillable="true" type="s:long" />
  </s:sequence>
</s:complexType>


It's little known that the SOAP Adapter is NOT sending the xml in the form and shape it received from the messaging engine. the actual processing in the method SetMethodAndParameters(MethodInfo method) under Microsoft.BizTalk.Soap.SoapMessage class includes deserializing the message parts into the required web method parameters as CLR objects. in this way, the SOAP adapter can find the matching operation even if there's more then one operation with the same name (don't forget that the SOAP Adapter is Reflection based). the final step is the Send() method that Invokes the proxy class (again, using Reflection).

The adapter is deserializing the xml into CLR objects using XmlSerializer.

So, what was really happening is that BizTalk was sending the message to the Soap Adapter. the adapter deserialized the object using the default XmlSerializer class and therefore all the Nullable<T> elements are ignored, at the end of the sending process the adapter serialized it again in the Invoke method of the proxy class and send the new xml to the web service.

Conclusion: To enable BizTalk Soap Adpater to serialize nullable value-type elements you need to remove the minOccurs="0" from all of the elements that contains nillable="true" attribute.

So, you have tow options:

  • Change the web-service itself.
  • Change only the wsdl file and then add the web reference from the fixed wsdl file.

If you choose the second option - just keep in mind that after every change or update of the web service, you need to get the new version of the wsdl, fix it by hand, and then - add the web referance from the fixed version, again.

Another thing to keep in mind is that you can't really be sure about the message BizTalk submitted through the Adapter Framework because the saving tracked massages from the orchestration using HAT is showing only the state in the Messaging engine before passing the message to the adapter for process and submit.

 
Copyright © 2007 | Diseñado por Blog and Web