wiki

Codit Wiki

Loading information... Please wait.

Codit Blog

Posted on Wednesday, February 7, 2018 1:20 PM

Pim Simons by Pim Simons

During a migration from BizTalk 2006R2 to BizTalk 2016 we ran into an issue with the “ESB Remove Namespace” pipeline component. This component is available out-of-the box when the ESB Toolkit is installed and is used to remove all namespaces from a message.

After successfully completing the migration and putting the new environment in production the customer also needed to process a new message. As with the other messages received in their BizTalk environment, all of the namespaces have to be removed from the message and a new one is added. For this the customer had used the “ESB Remove Namespace” and “ESB Add Namespace” pipeline components and this setup had been successfully migrated to BizTalk 2016. For more information on these pipeline components, see: https://msdn.microsoft.com/en-us/library/ee250047(v=bts.10).aspx.


However, when the new message was received by BizTalk we received this error:

Reason: The XML Validator failed to validate.
Details: The 'nil' attribute is not declared.

It turned out the XSD of the new message has a field that can be nillable, in the message we received the field was indeed marked as nillable. The “ESB Remove Namespace” pipeline component removed the xsi namespace and prefix which caused the “XML validator” pipeline component to fail!

Changing the message content or the XSD was not an option since the XSD was created and maintained by the external party which was sending us the message. We ultimately ended up recreating the “ESB Remove Namespace” pipeline component into a custom pipeline component and modifying the code.

The “ESB Remove Namespace” pipeline component contains code to process the Attributes which contains this snippet:
if (string.Compare(inReader.Name, "xmlns", StringComparison.OrdinalIgnoreCase) != 0 && !inReader.Name.StartsWith("xmlns:", StringComparison.OrdinalIgnoreCase))
{
                writer.WriteStartAttribute("", inReader.LocalName, "");
                writer.WriteString(inReader.Value);
                writer.WriteEndAttribute();
}
 
We replaced this with:
if (inReader.LocalName.ToLower() == "nil" && inReader.NamespaceURI.ToLower() == "http://www.w3.org/2001/xmlschema-instance")
{
                writer.WriteStartAttribute(inReader.Prefix, inReader.LocalName, inReader.NamespaceURI);
                writer.WriteString(inReader.Value);
                writer.WriteEndAttribute();
}
else if (String.Compare(inReader.Name, "xmlns", StringComparison.OrdinalIgnoreCase) != 0 &&
                !inReader.Name.StartsWith("xmlns:", StringComparison.OrdinalIgnoreCase))
{
                writer.WriteStartAttribute("", inReader.LocalName, "");
                writer.WriteString(inReader.Value);
                writer.WriteEndAttribute();
}
 
Now when we receive a message containing a node that is marked as nil, the custom “ESB Remove Namespace” pipeline component handles it correctly and the message is processed.

We could not find any information about the “ESB Remove Namespace” pipeline component not supporting nillable nodes on MSDN and I find it strange that the pipeline component does not support this. To me this seems like a bug.

Categories: BizTalk
written by: Pim Simons

Posted on Tuesday, December 8, 2015 1:40 PM

Robert Maes by Robert Maes

The ESB Toolkit is an extension for Microsoft BizTalk Server. It comes as an extra layer on top of BizTalk to make the routing and processing of messages even more easy than it already is by providing extra tools and libraries for the developer to use.

Via Itineraries, messages are transferred through the BizTalk application and mappings and services are resolved by different resolvers. There are some differences in the BRE when used as a resolver with the ESB toolkit that can give the developer some headaches.

When receiving a message in BizTalk using the ESB Toolkit, the first thing you have to do is define an itinerary. The itinerary contains different steps for the message to go to like services and mappings.

During a project I wanted to resolve these, based on the message content. I encountered some unexpected behavior during the development of this project and I wanted to share it because it almost gave me a headache.

Resolving 

Via the different resolvers, we can return itineraries, mappings, services, WCF bindings or variables that need to be executed in BizTalk. The most useful resolver is the Business Rules Engine. Because the BRE lets us decide what to return based on message content. This configuration can be managed in different policies.

Itinerary resolving

Via the default pipeline ItinerarySelectReceiveXml, we can use the ESB Itinerary Selector to select/resolve our itinerary.

Just use "Resolver.Itinerary" as ItineraryFactKey and use the BRI resolverConnectionstring to contact the Business Rules Engine(BRE) in the ESB Itineray Selector.

This will trigger the BRE to execute the chosen policy. The defined conditions are evaluated and certain actions will be executed. In this case returning the name of the preferred itinerary.

Now you should pay attention!

When using XPaths to evaluate the message content, the pipeline component doesn't send the correct document type to the BRE but a fixed value ='Microsoft.Practices.ESB.ResolveProviderMessage'.

This is also documented in the blogpost  https://talentedmonkeys.wordpress.com/2010/07/01/bre-rules-evaluation-in-esb-toolkit-document-types-are-incorrect/ but it is important for new ESB Toolkit users to situate this in the entire ESB Toolkit story.

When importing a schema in the BRE to use in an XPath, change the document type to 'Microsoft.Practices.ESB.ResolveProviderMessage'.

If the itinerary is resolved, then the ESB dispatcher will execute the itinerary. The service responsible for the routing of the message is the Microsoft.Practices.ESB.Services.Routing service. The mappings are executed in the Microsoft.Practices.ESB.Services.Transform.

Resolve mappings,services, ...

When resolving a mapping or a service based on the message content, make sure you are using the correct document type. In my case, we were using a schema with multiple root nodes.

The wanted transformation was not executed because the BRE couldn't find a rule that has conditions that return true in order to execute an action, being the returning of the transformtype.

The BRE suggested to use schemaname.rootnode. The ESB Toolkit however sends the fully qualified name: schemaname+rootnode to the BRE. After changing the documenttype in the BRE to the fully qualified name with '+' notation, the itinerary worked completely 

Tracing

To see what happens behind the screens, the trace option on the ESB toolkit can be used. Add following lines to the Machine.config:

 

Then use the debugview tool and connect to the Biztalk server to trace the logging of the esb toolkit.

 The selected itinerary and all the further steps can be seen here. It shows which messages are send to the ESB toolkit and the names that are used.

Categories: BizTalk
written by: Robert Maes