Configuring the ESB Toolkit 2.2 for BizTalk 2013 – Exception Creating the ExceptionDb
One of the great things about BizTalk 2013 is the improvements made in the installation of the ESB Toolkit. However, we’ve found lately, that there are still some issues that you should be watching for during configuration.
One issue, which I’ve seen twice now, has shown up while completing the very first configuration step in the ESB Toolkit 2.2’s configuration utility–creating the Exception Management database. Our configuration failed with this exception:
Exception Calling “create” with “0” argument(s) “Create failed for database esbExceptiondb’.”
The primary file must be at least 100 MB to accommodate a copy of the model database.
What We’re Getting in BizTalk 2013
The reports of my death have been greatly exaggerated.
-Microsoft BizTalk Server*
*also Mark Twain who was quite alive at the time he said this…
Over the last few years, rumors have been swirling around the BizTalk community regarding the life (or impending death) of BizTalk server. At Tech-Ed 2012 and the BizTalk Summit in December, Microsoft finally put those rumors to rest. Now BizTalk 2013 is more than just on the horizon, it’s available in RTM!
Here’s a quick list of what we’re getting with this release…
- Platform Updates (Visual Studio 2012, Windows Server 2012, SQL Server 2012, Office 2013, System Center 2012)
- Updated EDI and HL7
- Updated LOB Adapters for SAP, Oracle, and Siebel
- The ability to associate a host other than the default for dynamic send ports
- Improved performance for ordered send ports
- XslCompiledTransforms in maps
- Ability to view artifact dependencies (BIG win, here)
- SFTP
- REST Support (another HUGE win)
- Easier installation and configuration of the ESB Toolkit
- Connectivity to Azure Service Bus and Storage
- etc.
And one of the coolest things… BizTalk IN THE CLOUD! Besides the capability for adding BizTalk in a VM, BizTalk also will be available as part of the Azure “fabric” and will be integrated with the Azure management portal.
So lots of exciting stuff coming out. Pay attention, it’ll all be available soon! In the meantime, MSDN subscribers can access the RTM bits for BizTalk 2013 On-Premise right away!
ESB Toolkit Best Practices
I’ve been trying to put together a document of BizTalk best practices and have found a number of sources with a lot of great ideas. I’ll share what I’ve discovered at some point, but for now here’s one of my favorites.
It’s from Stott Creations regarding the ESB Toolkit. Below is a list taken directly from the article. Please read the full article (http://esb.stottcreations.com/biztalk-esb-toolkit-2-1-and-real-world-best-practices/) for more details:
Top 5 List of BizTalk Real-World Best Practices
Best Practice |
Benefits and Explanation |
In design, use the ESB Toolkit as the starting point – but not the endpoint. |
The ESB portal as delivered is to expose the capabilities of the ESB toolkit data and their relationships but is not a production grade site as-is. |
Just Enough Logging (JEL) – scale back logging post-go live to sane levels. Do not enable tracking for ports and orchestrations, and minimize the tracking of MsgBody. Do enable tracking on Biztalk server hosts. |
Logging every message is demanding on database and storage resources, and over time becomes less valuable. After deployment, administrators and users only care if BizTalk is running and if they have the ability to drill in on errors. As a general rule, the greater the amount of logging, the less said logging is used. Minimize and target the tracking and logging you actually need. |
Avoid complex deployment scenarios using shared custom core libraries |
As a rule of thumb, always exhaust all possible scenarios using out-of-the-box (OOTB) components to solve an issue before moving to custom code. Most scenarios can be accomplished by leveraging the samples provided, at the very least as a starting point. Shy away from starting from scratch. This also eases deployment and maintenance (no custom core components means nothing in the config files. Everything can be deployed in a comprehensive package) |
Write tightly focused, small components |
This promotes solid designs and reusability. Break up development in small units of work and string these solutions together in the itinerary. |
Your endpoints should always be resolved/configured via BRE over UDDI |
Power users often want to change endpoints and map types; the BRE as a resolver engine is the most powerful and flexible engine available. Comparatively UDDI both lacks intelligence and is has a complex interface configuration. |
Generating a BizTalk BRE Rule in .NET
As you can probably tell from other articles on this blog, I spend a great deal of time working with the Business Rules Engine (BRE) in BizTalk. Personally, I consider the BRE one of those great, often-overlooked technologies that should be used more than it is, but I digress…
One little-known thing you can do with the BRE is create rules on the fly in .NET. For this article, I’m going to provide a walk-through of how to do this.
First, though, you should spend a little time getting to understand the BRE if you don’t already. A great first step is to do the Virtual Lab provided by Microsoft.
The main artifacts in the BRE are Policies, Rules, Conditions, and Actions. At a very high level, we can describe a Policy as a container for a number of Rules. Each Rule contains a set of Conditions, which if true, will cause Actions to be performed. A Condition can use any number of Predicates such as EQUALS or GREATER THAN and Operators like AND and OR to evaluate the state of Objects, XML Documents, etc. An Action can be an assignment, a method call, or something performed on the same or other objects that may be sent in at execution time.
Before writing your Rule-Generating code, understand exactly what it is you wish to accomplish with the rule. What will the input be? XML Document? Business Object? What conditions will need to exist for a rule to fire? What will happen when the rule does fire?
Once you know which type of rule or set of rules you’d like to generate, it’s usually a good idea to map it out a bit first. For our purposes, we’re going to update an ESB Toolkit BRE Resolver object to set Routing information for a message along an itinerary. If you’d like to learn more about using the ESB Toolkit, I have a an introductory article on this blog or you may also check out the excellent videos by Peter Kelcey. However it is not important for understanding the main points of this article.
Our policy will contain only a single rule. Here’s the logic:
IF The incoming messages is of type "http://myMessageTypeNamespace#messageRoot" AND The ReceivePortName is "InboundMessagePort" THEN Set TransportLocation to: "C:\FileDrops\FileOut" Set TransportType to: "FILE"
First, reference the Rules Engine assemblies Microsoft.RuleEngine and Microsoft.Biztalk.RuleEngineExtension both located at <Program Files>\Common Files\Microsoft BizTalk\. Because we’ll also be accessing members of the Microsoft.Practices.ESB.Resolver.Resolution class for our conditions and actions, we’ll need a reference to Microsoft.Practices.ESB.Resolver as well. If you have the ESB Toolkit 2.1 installed, it is located at <Program Files>\Microsoft BizTalk ESB Toolkit 2.1\Bin\ . You may use classes in any .NET assembly here, just remember to alter your code and references accordingly.
After adding your references, add the following using statements:
using Microsoft.BizTalk.RuleEngineExtensions; using Microsoft.RuleEngine;
Before we can construct our conditions, we need to access the artifacts that will be used. For our example, it will be the Resolution class mentioned above. Here is the code we need to create a binding to this class so we can use it in our Business Rule:
ClassBinding resolutionClassBinding = new ClassBinding( typeof(Microsoft.Practices.ESB.Resolver.Resolution));
We’ll also need to create bindings for the class members we want to evaluate. Note the names we use for the properties we’ll be evaluating. You’ll see names like “get_MessageType” instead of “MessageType” and “get_ReceivePortNameField” instead of “ReceivePortName”. At lower levels in the BRE code, properties are often accessed by calling a get_ or set_ function. An easy way to look up the names the engine will use is to load the class in the Facts Explorer in the Business Rules Composer and look at their names there.
Create instances of ClassMemberBinding, passing in the name of the members and the ClassBinding we created previously:
ClassMemberBinding messageTypeBinding = new ClassMemberBinding( "get_MessageType", resolutionClassBinding); ClassMemberBinding receivePortNameBinding = new ClassMemberBinding( "get_ReceivePortNameField", resolutionClassBinding);
Next, we construct the logic. First, we’ll build each IF condition individually, add them to a collection of Logical Expressions, and ensure that we evaluate them all together with an And.
LogicalExpression messageTypeCondition = new Equal( new UserFunction(messageTypeBinding), new Constant("http://myMessageTypeNamespace#messageRoot")); LogicalExpression portNameCondition = new Equal( new UserFunction(receivePortNameBinding), new Constant("InboundMessagePort")); LogicalExpressionCollection conditionsList = new LogicalExpressionCollection(); conditionsList.Add(messageTypeCondition); conditionsList.Add(portNameCondition); LogicalAnd allConditions = new LogicalAnd(conditionsList);
After creation of the conditions, the next step will be to build out the actions that will take place should the conditions evaluate to true. For our purposes, the output values will be hard-coded, but you can use other rule inputs or method calls to create your values. First we start with an ActionCollection:
ActionCollection actions = new ActionCollection();
Now to add the actions to the list, we’ll need to create bindings to the class and its members that we’re interested in. As before, it’ll be references to members of the Resolution class. We’ll start by creating an ArgumentCollection and the ClassMember objects needed to bind to our list of Actions for the transport location method:
ArgumentCollection locationArgs = new ArgumentCollection(); locationArgs.Add(new Constant(@"C:\FileDrops\FileOut")); ClassMemberBinding locationBinding = new ClassMemberBinding( "set_TransportLocation", resolutionClassBinding, locationArgs);
Next, the we’ll bind the Transport Type:
ArgumentCollection transportArgs = new ArgumentCollection(); transportArgs.Add(new Constant("FILE")); ClassMemberBinding transportBinding = new ClassMemberBinding( "set_TransportType", resolutionClassBinding, transportArgs);
Now, add them to our Actions collection:
actions.Add(new UserFunction(locationBinding)); actions.Add(new UserFunction(transportTypeBinding));
Then we’ll create a Rule, add all the conditions and actions to it, and assign it to a new policy (or RuleSet). Our policy will use the default version, but you can also use the VersionInfo class to add your own major and minor version assignments.
Rule sampleRule = new rule("sampleRule", allConditions, actions); RuleSet newPolicy = new RuleSet("samplePolicy"); newPolicy.Rules.Add(sampleRule);
Finally, we’ll need to deploy it to the BRE. We’ll need to publish and deploy the rule in two separate steps:
Microsoft.BizTalk.RuleEngineExtensions.RuleSetDeploymentDriver deploymentDriver = new Microsoft.BizTalk.RuleEngineExtensions.RuleSetDeploymentDriver(); RuleStore breStore = deploymentDriver.GetRuleStore(); // add the RuleSet to the database and publish it try { breStore.Add(newPolicy, true); } catch (RuleStoreRuleSetAlreadyPublishedException) { Console.WriteLine("Warning: Ruleset \"" + newPolicy.Name + "\" is already published"); return; } // now deploy the ruleset try { deploymentDriver.Deploy(new RuleSetInfo(newPolicy.Name, newPolicy.CurrentVersion.MajorRevision, newPolicy.CurrentVersion.MinorRevision)); } catch (RuleEngineDeploymentAlreadyDeployedException) { Console.WriteLine("Warning: Ruleset \"" + newPolicy.Name + "\" is already deployed"); return; }
And that’s it.
Here’s an image of the policy we generated in the Business Rules Composer:
Of course, there’s much more you can do than what is shown here but hopefully this sample code can help you get started. In a future post, we’ll discuss how to use a regular XML message in your rules instead of just method calls in .NET assemblies as shown here.
ESB Toolkit 2.1 Portal Installation (x64) Gotcha – Update the VS Path in PowerShell Scripts
The installation process for th ESB Toolkit has never been painless. Version 2.1 did not improve this at all. The installation of the ESB Portal is particularly so, as the PowerShell scripts used to set it up are very buggy.
For example, you may find that nothing that is supposed to build using the dev environment (devenv.exe) will build. That’s usually because near line 18 in Management_Install.ps1 you’ll find this variable declaration:
$env:VS="${env:ProgramFiles}\Microsoft Visual Studio 10.0\Common7\IDE"
You may will need to alter the line to something like this:
$env:VS="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE"
or
$env:VS="${env:ProgramFiles(x86)}\Microsoft Visual Studio 10.0\Common7\IDE"
The problem is that most Visual Studio 2010 installations install to the “Program Files (x86)” folder rather than “Program Files”. This will cause many of the pieces of the sample installation PowerShell scripts to fail unless you make this change.