Table of Contents
1. Technology Primer.
2. BizTalk Architecture.
3. Adapters.
4. Pipelines.
5. Orchestration.
6. Business Activity Monitoring.
7. Business Rules Engine.
8. Testing.
9. Performance and Scalability.
10. Low Latency.
11. Administration.
12. End-to-End Scenarios.
13. BizTalk Best Practices.
14. Windows Workflow and BizTalk.
Index.
Read a Sample Chapter
Professional BizTalk Server 2006
By Darren Jefford Kevin B. Smith Ewan Fairweather John Wiley & Sons
Copyright © 2007 John Wiley & Sons, Ltd
All right reserved. ISBN: 978-0-470-04642-5
Chapter One
Technology Primer Microsoft .NET software development relies on a wide range of technologies and "tricks of the trade." Some of these you might not be familiar with and others you may already use on a day-to-day basis. We'll cover a number of areas of particular relevance and value to BizTalk Server development projects to ensure we're all on the same page as we progress through the book.
Specifically, this chapter introduces the following concepts that apply to software development in general rather than to BizTalk in particular. In my experience, understanding these concepts is key to development and debugging.
XML Schema
XML namespaces
XPath
Serializable classes
This chapter is meant simply to be an introduction to these topics and does not cover them in depth or discuss all of their aspects; there are many books and online resources that will cover them in depth. If, however, you are familiar with these topics then feel free to move on to the next chapter.
XML Schema
XML Schema is a World Wide Web Consortium (W3C) standard for defining thestructure and content of Extensible Markup Language (XML) documents. In short, this means that you can define how an XML document should look and what types any data in it should conform to; it is a form of data contract, if you like. BizTalk is driven by messages, which, in most cases, are based on an XML schema that must be deployed to BizTalk.
The following is an example of a simple schema used to describe a person:
This schema defines an element called Person that contains a complex type, which, in its simplest form, is a collection of subelements (like a class in object-oriented programming). Two further elements with differing data types have been defined within this complex type.
The following is the XML document that conforms to this schema:
Lucy 5
Defining the schema in this way enables you to enforce how you expect data to be encoded or represented. This schema can be given to any consumers of your application to ensure that they respect this contract and it enables them to communicate with you easily.
You can also use the schema to validate any incoming XML documents, which can eliminate the need for extensive data checking inside your application and improve the overall reliability of your solution.
BizTalk Server 2000 and 2002 used an earlier "schema" standard called Document Type Definition (DTD). DTD has subsequently been superseded by XML Schema, hence the native support for schemas in BizTalk Server 2004 and 2006. If you have DTD files that you wish to leverage, you can migrate them to XML Schema by using the Add Generated Items feature, which is accessible by right-clicking your BizTalk project in the Visual Studio Solution Explorer.
XML Namespaces
Namespaces in XML documents are conceptually the same as namespaces in .NET. Any types you define are "enclosed" within the context of the specified namespace. This ensures against name clashes and allows content from multiple sources to be stored within the same document but still be isolated, as required.
Namespaces are used within XML documents and, therefore, BizTalk messages. Namespaces can often be the cause for problems when integrating different systems, when a message doesn't use the correct namespace and, therefore, doesn't comply with the appropriate schema.
The following XML document specifies that the Person element and its contents are within the "http://www.wiley.com" namespace. (This is called a default namespace.)
Lucy 5
The following XML document shows how you can explicitly set the namespaces, in contrast to the default namespace example shown before. The Person element is contained within the "http:// www.wiley.com/person" namespace, and the Address element is defined within the "http://www .wiley.com/address" namespace.
Instead of having to prefix the nodes with the full namespace name, you can use aliases. In this instance, we've used ps and ad, which allows easier reading and, of course, a smaller payload on the wire, as less text will need to be transmitted.
Lucy 5 Chippenham
As you can see, namespace names are typically specified as URLs, which can be confusing because people tend to assume that they must point to something on the Internet. They don't have to but often do. A namespace name can be any form of URL.
This holds true for .NET namespaces as well. Microsoft, for example, tends to prefix its code in the Microsoft or System namespaces.
XPath
XPath is a navigation language for finding information held in an XML document. Navigation is described using "expressions," which in their basic form are analogous to the paths you use to navigate the filesystem on Windows.
XPath is used by BizTalk messaging and orchestrations to retrieve interesting pieces of data from a message, which can then be used to route the message or perform a conditional business process. As with namespaces, a little understanding of XPath can go a long way toward helping you diagnose problems during development.
An XPath expression returns a node or collection of nodes called a node set and in some cases the result of a function - a integer representing a count for example. The XPath expression /ps:Person/ps:Name will return the Name node of the following XML document.
Toby 3 Chippenham
As you may have noticed, the namespace prefixes have been used in the XPath expression. Because XPath is "namespace aware," if namespaces are omitted, it will be unable to find the node. Omitting the namespaces in this way will cause XPath to use only the default namespace. So if /Person/Name were to be used, it would not exist outside of the correct namespace.
The .NET code to retrieve the Name element from the preceding document is shown below. Note that the namespace alias used in the XPath query is different from the alias used in the XML document above.
Aliases are not part of the document structure; they just refer to the namespace name. Under the covers, the namespace alias is expanded to the full namespace. In the following code, you can see that you have to register a namespace prefix so that it will point at the namespace name. This alias can be anything, as long as it points to the underlying namespace definition.
Developers are often confused by namespace aliases. When faced with XML documents that BizTalk has received or generated, you might find that the namespace aliases differ from a sample XML document you are working against and assume they are wrong, when in fact they are actually the same. I have seen issues with Web services deployed on other platforms, where the developers have assumed that the namespace alias will be a fixed name and subsequently the webservice fails to work when a perfectly valid XML document is transmitted that uses different alias names. This is incorrect behavior on the service end and should be corrected wherever possible
This alias is then used in the XPath expression to retrieve the Name element. The following code uses the .NET XPathDocument and XPathNavigator classes, which are part of the System.Xml namespace and provide the ability to use XPath expressions efficiently against XML documents:
XPathDocument doc = new XPathDocument("person.xml"); XPathNavigator nav = doc.CreateNavigator();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(nav.NameTable); nsmgr.AddNamespace("p", "http://www.wiley.com/person");
foreach ( XPathNavigator node in nav.Select("/p:Person/p:Name",nsmgr)) { Console.WriteLine(node.Value); }
The XPath language is comprehensive and offers a variety of mechanisms with which to retrieve data. We won't cover them all here, but we will pull out a couple of useful techniques for BizTalk Server development.
You may have noticed the use of XPathDocument and XPathNavigator in these examples rather than XmlDocument, which is often used. The XPathDocument uses a read-only, in-memory tree that is optimized for XPath expressions and the Extensible Style Language Transformation (XSLT) language.
The local-name Function
As you've probably already noticed, BizTalk uses XPath in a number of areas - pipeline component configuration and property promotions are two examples. In both of these areas, BizTalk builds the XPath statement for you but uses an XPath function called local-name.
As the name implies, the local-name function returns the name of the XML element in the local context. Therefore, if an XML element has a namespace prefix, it's considered to be within that namespace. Using local-name removes the namespace prefix and returns the raw element name, thus eliminating the need to jump through the hoops you had to when using the XmlNamespaceManager previously.
The following code returns exactly the same information as the previous code sample and is far simpler as a result of using the local-name function. You should also bear in mind that use of the local-name function incurs slightly more overhead because it has to perform extra processing.
XPathDocument doc = new XPathDocument("person.xml"); XPathNavigator nav = doc.CreateNavigator(); foreach (XPathNavigator node in nav.Select("/*[local-name()='Person']/* [local-name()='Name']")) { Console.WriteLine(node.Value); }
About 90 percent of all the XPath "problems" I've ever seen have been rooted in namespace problems. A quick way to see if you're hitting such problems is to try using local-name in your XPath expressions. Although I wouldn't recommend it by default for everything, as it may cause problems in a project where there could be conflicting types. Namespaces are there for a reason!
The count Function
The count XPath function, as the name implies, enables you to count the number of elements matching an XPath expression, which is useful if you want to calculate the number of line items in an order, for example.
The following XML document and code counts the number of Person elements present in the XML document.
Lucy 5 3
XPathDocument doc = new XPathDocument("person.xml"); XPathNavigator nav = doc.CreateNavigator();
int count = Convert.ToInt32(nav.Evaluate("count(/*[local-name()='People']/ *[local-name()='Person'])"));
This technique is handy for times when you need to calculate the number of items in an XML document and then initiate a Loop shape in a BizTalk orchestration.
A number of other XPath functions are supported. Table 1-1 lists the functions supported at the time of this writing for reference. Check the MSDN documentation for the latest list.
Serializable Classes
Serializable classes are one of the more powerful features of the .NET Framework and, sadly, one of the most overlooked, largely because there is no native IDE support to generate them and, therefore, their existence is not obvious to developers.
Despite this, you do end up using them whenever you return a class type from an ASP.NET Web service method. Under the covers a serializable class is generated for you to handle the class being transmitted across the wire in a Simple Object Access Protocol (SOAP) envelope.
By their very definition, serializable classes are classes that can have their "content" dehydrated for later use. The .NET implementation allows serializable classes to be dehydrated to any form of Stream.
Many API's in the .NET Framework use the concept of streams, which represent an abstract view of data by presenting it in a contiguous sequence of bytes that you can read or write. Thus, they isolate you from any underlying data store, such as a file, serial port, or network connection. This is useful because it enables you to write to and read from a variety of "stores" using the same application programming interface (API).
The following code uses a StreamReader to write to a Memory and File stream demonstrating the ability to use a generic "writer" against different stores.
using (MemoryStream ms = new MemoryStream()) { StreamWriter writer = new StreamWriter(ms); writer.WriteLine("Hello World!"); }
using (FileStream fs = new FileStream("output.txt", FileMode.Create)) {
StreamWriter writer = new StreamWriter(fs); writer.WriteLine("Hello World"); }
If you want to serialize a .NET class to a stream, you need to decorate the class with a [Serializable] attribute, which tells the .NET runtime that your class is allowed to be serialized.
(Continues...)
Excerpted from Professional BizTalk Server 2006 by Darren Jefford Kevin B. Smith Ewan Fairweather Copyright © 2007 by John Wiley & Sons, Ltd. Excerpted by permission.
All rights reserved. No part of this excerpt may be reproduced or reprinted without permission in writing from the publisher.
Excerpts are provided by Dial-A-Book Inc. solely for the personal use of visitors to this web site.