At the moment I'm working on integrating the great Pipeline Component Wizard by Martijn Hoogendoorn into the BizTalk Software Factory. I decided to use a T4 template to get the job done. T4 templates are very powerful and easy to write (but hard to debug, as I found out). This post is dedicated to what I ran into while developing the templates.

The issues I had to deal with were:

  • Changing the wizard into a custom wizard
  • Getting the data out of the wizard into the T4 template
  • Processing the data in the T4 template to get the right code generated
  • Debugging T4 templates
  • Figuring out why I ran into the error "The given key was not present in the dictionary"

     

First of all, the current implementation of the PLCW wasn't functioning on systems with GAT installed. That was the basic reason to change the wizard. The PLCW is based on the Microsoft.BizTalk.Wizard framework. The custom wizard pages in the guidance inherit from the Microsoft.Practices.WizardFramework.CustomWizardPage class and the wizard of the PCLW couldn't be used 1-on-1. One of the reasons for that is that it is important for the CustomWizard page to have the following constructor:

public MyCustomWizardPage(WizardForm parent) : base(parent)
{
   // This call is required by the Windows Form Designer.
   InitializeComponent();
}

Among other things like the way the wizard saves state between pages, I decided to reuse the pages but inherit them from the CustomWizardPage.

The wizard collects some data to use in the pipeline component creation process and everybody who is familiar with the PLCW knows you can define custom design properties at the end of the wizard. I thought it was a good idea to create a small class for that to contain the type/name values and put that into a generic list for ease of use.

For every variable you want the wizard save between pages and have available at the end, you should define an argument in your recipe. So I defined like this:

<Argument Name="ClassName" Type="System.String" />
<Argument Name="DesignPropertyList" Type="System.Collections.Generic.List<MyDesignProperty>" />
 

Everybody with a bit of XML knowledge understands that this isn't going to work, so I looked at some samples and changed it into this:

<Argument Name="DesignPropertyList" Type="System.Collections.Generic.List&lt;MyDesignProperty&gt;" />
 

In the code of the custom wizard pages, you can write and read the arguments like this. Make sure the name used in 'SetValue' is exactly the same as the argument.

IDictionaryService dictionaryService = GetService(typeof(IDictionaryService)) as IDictionaryService;
dictionaryService.SetValue("ClassName", txtClassName.Text);
 

  • Make sure every argument has a value otherwise you will end up with error messages saying the specific argument is empty.

So now I have defined the necessary arguments and created the custom wizard pages and now I want to use the arguments in a T4 template action. For that I need in fact 2 actions:

  • Generate the content with Microsoft.Practices.RecipeFramework.VisualStudio.Library.Templates.TextTemplateAction
  • Write the content to file with Microsoft.Practices.RecipeFramework.Library.Actions.AddItemFromStringAction

I defined the arguments as properties in the T4 template, but it didn't work. I didn't receive the generic list with design property values as I saved into the arguments in the wizard. After a long search I found that a generic class isn't supported by this action. How to solve this? I downloaded the Smart Client Software Factory and the Web Services Software Factory to peek at their solution (they are quite good at this, I can tell you that). There appeared to be a simple solution for this like defining an empty new 'collection' class like this:

public class MyDesignPropertyCollection : List<MyDesignProperty>
{
}

So I had to change the argument again into:

 <Argument Name="DesignPropertyList" Type="BizTalkSoftwareFactory.BusinessEntities.MyDesignPropertyCollection, BizTalkSoftwareFactory" />

In the T4 template the value should be specified as this:

<#@ Assembly Name="BizTalkSoftwareFactory.dll" #>
<#@ Import Namespace="BizTalkSoftwareFactory.BusinessEntities" #>
<#@ property processor="PropertyProcessor" name="DesignPropertyList" #>
 

One of the other issues is that I was uncertain what I received in the T4 template. Debugging T4 templates can be hard although there seems to be tools available. I used a custom debug class to be able to view the available values in the template. I defined a method which I call in the beginning of the template:

<#  TemplateHelper.DebugThis(this); #>

Of course you need to import the namespace where the method can be found:

 <#@ Import Namespace="BizTalkSoftwareFactory.BusinessComponents" #>

So I now have generated content which I need to write to file, that is what the second action is for. It takes the output of the previous action, location to add the file to and name of the file. That doesn't look too difficult as I used it already in the Unit test part. So I copied that part of the recipe and then I ran into the error "The given key was not present in the dictionary" and I really didn't understand where it came from. I compared the code and it looked the same. At these times it can be very frustrating not to be able to debug, as I found out I didn't even get into the second action. I grabbed the code using reflector and created my custom action with that code, but the error showed up even before entering the action.

Now what?

Literally hours later I found what caused the action and of course afterwards it is always easy.

I defined the action like this:

 <Action Name="AddPipelineComponent" Type="Microsoft.Practices.RecipeFramework.Library.Actions.AddItemFromStringAction, Microsoft.Practices.RecipeFramework.Library" Open="true" >
  <Input Name="Content" ActionOutput="GeneratePipelineComponent.Content" />
  <Input Name="TargetFileName" RecipeArgument="PipelineComponentFileName" />
  <Input Name="Project" ActionOutput="PipelineComponentProject" />
</Action>

The problem is in the "ActionOutput" for input "Project". Logically "ActionOutput" means……..output of an action and that wasn't the case. It was a regular "RecipeArgument". Very easy to fix, but hard to find.

So if you run into the error "The given key was not present in the dictionary", think about this it will save you hours. J

If you need guidance with generic lists and wizards/actions I would advise you to look at the Smart client software factory and the Web service Software Factory.

 It took me a while, but v1.0 of the BizTalk Software Factory is finally on CodePlex.

You can get it from http://www.codeplex.com/bsf

This first release took CodePlex/BASF developed by Dijkstra as a basis and added some functionality.

  • Create BizTalk multi project solution structures using a wizard
  • Create BizTalk single project solution, grouping artifacts into folders, using a wizard
  • Guidance for adding Schemas to a project
  • Guidance for adding Maps to a project
  • Guidance for adding Orchestrations to a project
  • Guidance for adding pipelines to a project

Future releases will contain also Unit Test and setup projects.

with 5 comment(s)
Filed under:

On the project I'm working on at the moment we're using custom exceptions in BizTalk. We have adopted the exception handling part of the ESB guidance and so the custom exception consists of a string indicating what to do next and an XLANGMessage object to store messages in.

There was something not working as expected so I had to debug it. I wasn't very familiar with custom exceptions in BizTalk so I searched the internet for some information. On this blog by Tomas Restrepo I found some interesting tips and information:

Tip #1: Exceptions are not serializable by default. If you create a custom exception class, it is your responsibility to ensure it is serializable.

Tip #2: Marking an exception class with [Serializable] is not enough. System.Exception implements ISerializable, so it forces you to do so as well.

Here's what you should keep in mind when writing an exception class:

  • Mark the exception type with the [Serializable] attribute.
  • Add an empty protected serialization constructor that simply delegates to the base class: protected MyException(SerializationInfo info, StreamingContext ctxt) : base(info, ctxt)

For most exception classes, this will be enough, since most don't actually add new properties and simply rely on the message.

However, if your custom exception class has custom properties, then it MUST override ISerializable.GetObjectData() (and don't forget to call the base one), and you MUST unpack those properties in your serialization constructor.

While testing the solution I found out that something went wrong after the custom exception was returned to the orchestration. All information was present in the object but the messages could not be retrieved. I was puzzled. It looked like something in the serialization/deserialization process of the XLANGMessage object failed, but if one object should be serializable it should be this object. Right?

Further research showed that the XLANGMessage object was serialized/deserialized ok, but the XLANGPart object wasn't. This resulted in a correct XLANGMessage structure, with the correct number of parts in it, but with empty content. As a last resort I posted a question on the MSDN forum.

Within a day I had the solution. It turned out that the XLANGMessage property containing the XLANGParts data wasn't public so with binary serialization it was skipped. That at least explained this behavior, but how to solve it? In fact that was also in the reply (thanks Douglas Marsh) and in the Tomas Restrepo blog. You have to manually get the parts that aren't serializable and put them in the SerializationInfoStore in the GetObjectData method. Like this:

         public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
            if (info != null)
            {
                info.AddValue("Fault", this.Fault, typeof(XLANGMessage));
                // Get the message parts, they aren't serializable so we have to do it by hand
                // Get the contents of the parts, convert them to a byte[] and add them to the store
                if (this.Fault != null)
                {
                    info.AddValue("NumberOfFaultParts", this.Fault.Count, typeof(Int32));
                    for (int i = 0; i < this.Fault.Count; i++)
                    {
                        info.AddValue("FaultMsgPart" + i, Helper.XmlDocumentToByteArray((XmlDocument)this.Fault[i].RetrieveAs(typeof(XmlDocument))), typeof(byte[]));
                    }
                }
            }
        }

When deserializing you can get them back in the serialization constructor, like this:

        protected MyCustomException(SerializationInfo info, StreamingContext ctxt)
            : base(info, ctxt)
        {
            if (info != null)
            {
                // get all the public members
                this.Fault = (XLANGMessage) info.GetValue("Fault", typeof(XLANGMessage));
                // Get the message parts, they aren't serializable
                // This has to be in a try block, because the 'NumberOfFaultsParts' isn't always there and there is no way of knowing in advance
                try
                {
                    int faultPartsCnt = info.GetInt32("NumberOfFaultParts");
                    for (int i = 0; i < faultPartsCnt; i++)
                    {
                        XmlDocument doc = Helper.ByteArrayToXmlDocument((byte[])info.GetValue("FaultMsgPart" + i, typeof(byte[])));
                        this.Fault[i].LoadFrom(doc);
                    }
                }
                catch (Exception ex)
                {
                    Trace.WriteLine("XLANGPart serialization error: ", ex.Message);
                }
            }
        }

So after all it wasn't that difficult at all, but isn't that always the case?? Thanks to everybody helping me.

with 1 comment(s)
Filed under: ,

On a blogpost by Yossi Dahan I read about a BizTalk tool I didn't know about: MsgBoxViewer

 

Via Google I couldn't find much about it so I decided to unpack it and try it. This was a very easy process because it doesn't require any installation, just unpack and run the GUI.

It appears to be a tool able to gather information about the status of your BizTalk environment, also with 'Best Practices Analyzer'-like features.

The name of the tool suspects that only the MessageBox is checked, and it does show the condition of your database, but the tool can do much much more.

The tool is written by Jean-Pierre Auconie, a Tech Lead in the European MS BizTalk Support team. He started developing this tool to ease the process of getting information from customers while trying to solve their problems.

 

Take a look at it yourself, it can be downloaded here.

with no comments
Filed under:

In an earlier post I wrote about Microsoft researching possibilities for BizTalk Server 2006 supporting the latest Windows, SQL Server and Visual Studio releases.

Today I read a blogpost by Richard Seroter who writes about a new release of BizTalk Server 2006 marked as R3 is scheduled for the first half of 2009, this was announced by Steve Martin (Microsoft CDS).

So R3 will support:

  • Window Server 2008
  • SQL Server 2008
  • Visual Studio 2008

Besides that there will be some enhancements and additions

"We are also taking the opportunity as part of this BizTalk Server release to deliver additional customer-requested capabilities for our core SOA infrastructure.  We will give more updates on specific features in the coming months, but at a high level we are planning some new investments in the release that includes: "

  • New web service registry capabilities with support for UDDI (Universal Description Discovery and Integration) version 3.0
  • Enhanced service enablement of applications (through new and enhanced adapters for LOB applications, databases, and legacy/host systems
  • Enhanced service enablement of “edge” devices through BizTalk RFID Mobile
  • Enhanced interoperability and connectivity support for B2B protocols (like SWIFT, EDI, etc
  • SOA patterns and best practices guidance to assist our customer’s implementations

However, this release does not correspond to the Oslo project.

with 3 comment(s)
Filed under: ,

From the Microsoft site: 

The BizTalk Server 2006 Best Practices Analyzer performs configuration-level verification by reading and reporting only. The Best Practices Analyzer gathers data from different information sources, such as Windows Management Instrumentation (WMI) classes, SQL Server databases, and registry entries. The Best Practices Analyzer uses the data to evaluate the deployment configuration. The Best Practices Analyzer does not modify any system settings, and is not a self-tuning tool.

Download it here:

http://www.microsoft.com/downloads/details.aspx?FamilyId=DDA047E3-408E-48BA-83F9-F397226CD6D4&displaylang=en

 

with no comments
Filed under:

I just read a post saying that Microsoft is investigating options for BizTalk support in Visual Studio 2008 and have BizTalk run on Windows Server 2008 and SQL Server 2008. It is all scheduled for this year so that is good news!

 http://blog.paul.somers.com/blog/_archives/2008/2/25/3544308.html

with 1 comment(s)
Filed under:

I was working on a PC on which I wanted to install the BAM definitions that come with the ESB guidance for exception handling.

So I browsed to the <installpath>\ESB Exception Handling Install\Install\BAM folder to execute "deploy_exception_tracking.cmd".

Unfortunately I was unable to run it because it requires Excel to be present to process the Excel file containing the definitions and that wasn't installed on that machine. On the other hand I wasn't allowed to install Excel so I had to convert the XLS to XML which also can be used to import the definitions. On my external drive I found an VPC with Biztalk 2006 and Excel installed and used that to let Excel generate the XML.

With renewed energy I changed the ESB deployment file "bmdeploy.cmd" to use the XML instead of the XLS. If you want be able to undeploy it again, also change the "bmundeploy.cmd".

It ran some time and then returned the following error:

Updating Activity... ERROR: The BAM deployment failed.
Encountered error while executing command on SQL Server "VPC-BT2006".
New request is not allowed to start because it should come with valid transaction descriptor.

After some searching I found that it had to do with a bug in ADO.NET that would be fixed in SP2 of SQL Server 2005. So I installed it and tried again. Again the same error. Further research was necessary to find the cause.

At the end it turned out to be a SQL Hotfix fixing it because SP2 didn't.

The XML file with the representation of the BAM definitions in XML can be found here.

Some other thing that I rediscovered is the location of the Excel plugin for BAM. I was used to BizTalk 2004 where BAM.XLS was the Excel sheet to use. Now that one is gone and a plugin is used. Microsoft tells you where to look for it:
If Excel 2003 is not installed, the file BAM.xla is installed to its default location at %System Drive%\Program Files\Microsoft BizTalk Server 2006\Exceldir. If Excel is installed, it can directly be added as plugin using the Tools menu.

with no comments
Filed under: ,

This is more or less a note to self because I probably will run into this again.

Today I was cleaning up the code tree in TFS and found a project that could be deleted. Unfortunately the developer left the company leaving a file checked out. With the Source Control Explorer it wasn't possible to remove the project as long as there were locked files. The file status is stored in the workspace, so deleting it would solve the problem

Using the TF.exe commandline tool it was possible to lookup ad delete that workspace.

Getting the workspace name:

tf workspaces /owner:<developers_logonname> /computer:* /server:<your TFS server>

Deleting the workspace:

tf workspace /delete /server:<your TFS server> workspace_name;developers_logonname

Remember that you need AdminWorkspaces global permissions to be able to delete the workspace.

 

with no comments
Filed under:

In the past few weeks I have been installing the ESB guidance for BizTalk server. Yes, it took me a few weeks because it isn't as easy as clicking setup.exe. Of course I wasn't busy all day during that time, but actually it took me longer than I expected. I read the discussions on CodePlex and I ran into some of the problems mentioned there but also found some new ones. During the installation process I decided to create an install script with issues I faced.

I didn't install the MQ/JMS components so please refer to the guidance documentation if you want that. Here is the script I created, maybe it will help you install the ESB package.

Software requirements:
- Microsoft Windows Server 2003 with Service Pack 2 installed
- Microsoft .NET Framework 3.0
- Hot fix KB923028 (this fixes the "Unhandled Exception: System.AccessViolationException" error when you run a .NET Framework 2.0 Remoting application, see http://support.microsoft.com/kb/923028)
- Internet Information Services (IIS) 6.0 (used for Web services and the ESB Management Portal)
- SQL Server 2005 SP2 including the Database Service, Analysis Services, and Integration Services; or SQL Server 2000 including the Database Service and Data Transformation Service, and with Service Pack 3 or later installed
- Visual Studio 2005 (C# for most projects; C++ for the JMS pipeline component) with Service Pack 1 or later installed
- InfoPath 2003 or InfoPath 2007 (used to render exception details generated by the ESB Exception Management Framework)
- Excel 2003 or Excel 2007 (required only to modify the BAM tracking spreadsheets)
- Enterprise Library 3.1 (this is required only for the ESB Management Portal)
- Windows Sysinternals DebugView; this is highly recommended to enable you to see trace information as messages flow through the ESB, which can be useful when troubleshooting (available from http://www.microsoft.com/technet/sysinternals/Miscellaneous/DebugView.mspx)
- Microsoft BizTalk Server 2006 R2, including Business Activity Monitoring (BAM)
- BizTalk MQ Series Adapter installed and configured using the default name (only if using the Microsoft ESB Guidance JMS component or the samples that require MQSeries)
- BizTalk Server 2006 R2 Hotfix KB943871, which adds support for new BizTalk Error Reporting properties (ErrorReport.FailureTime, ErrorReport.FailureAdapter, ErrorReport.FailureMessageID, ErrorReport.FailureInstanceID)
(but the hotfix KB943871 doesn't seem to be around)

Before moving on make sure the default website is running ASP.NET 2.0 (1.1 is default, which affects all virtual directories expecting ASP.NET 2.0)

- Install UDDI (Add/remove software - Windows Components)
- Install the Dundas Chart for ASP.NET Enterprise (download from http://www.dundas.com/Downloads/index.aspx)

* reminder: Microsoft ESB Guidance source and sample code is distributed as a .zip file. In the current release, the supported installation is for the files to reside in the folder C:\Projects\Microsoft.Practices.ESB. The BizTalk binding files that ship with the samples depend on this path.

Installation of the ESB package:
- Install ESB by executing ESB Guidance November 2007.msi
- Create a "Tmp" folder and copy the "ESBource.zip" archive to it (to avoid long names issues)
- Create folder "C:\Projects\Microsoft.Practices.ESB"
- Extract "ESBource.zip" with folders to "C:\Projects\Microsoft.Practices.ESB"
- Execute SQL script "EsbExceptionDb_CREATE.sql" to create exception database
- Open "PreProcessingCORE.vbs" and change User and Pwd to your settings
- Execute "PreProcessingCORE.vbs"
- Check http://support.microsoft.com/kb/215383 to verify if security settings are correct
- Execute "1.Install_Prerequisites.cmd"
- If errors occur, restart the MSSQL$UDDI service (UDDI is a named instance) and try again
- Execute "1. CORE_CreateBizTalkApplication.cmd"
- Change the SQL adapter setting on the All.Exceptions Sendport to the database containing the EsbExceptionDb

Configuration:
Change Biztalk config file %ProgramFiles%\Microsoft BizTalk Server 2006\BTSNTSvc.exe.config
- Add the following section to the BTSNTSvc.exe.config file immediately below the opening <configuration> element
 
  <configSections>
    <section name="xlangs" type="Microsoft.XLANGs.BizTalk.CrossProcess.XmlSerializationConfigurationSectionHandler, Microsoft.XLANGs.BizTalk.CrossProcess" />
  </configSections>

- Add the following section to the end of the BTSNTSvc.exe.config file, immediately above the closing </configuration> element

  <xlangs>
    <Configuration>
      <AppDomains AssembliesPerDomain="10">
        <DefaultSpec SecondsIdleBeforeShutdown="1200" SecondsEmptyBeforeShutdown="1800"/>
        <AppDomainSpecs>
          <AppDomainSpec Name="Microsoft.Practices.ESB">
            <BaseSetup>
              <ConfigurationFile>
                [path]\Microsoft.Practices.ESB.PipelineComponents.config
              </ConfigurationFile>
            </BaseSetup>
          </AppDomainSpec>
        </AppDomainSpecs>
        <PatternAssignmentRules>
          <PatternAssignmentRule AssemblyNamePattern="Microsoft.Practices.ESB.*" AppDomainName="Microsoft.Practices.ESB" />
        </PatternAssignmentRules>
      </AppDomains>
    </Configuration>
  </xlangs>

- Change the [path] placeholder with the location where Biztalk can find the configfile "Microsoft.Practices.ESB.PipelineComponents.config"
That is for example c:\Projects\Microsoft.Practices.ESB\Source\Core\Config if you used the solution deployent of ESB and If you are installing from the Microsoft.Practices.ESB.CORE.msi Windows Installer, the default path is C:\Program Files\Generated by BizTalk\Microsoft.Practices.ESB\Config.

- Restart the BizTalk NT Services

Change .NET config file %WinDir%\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config
- Add the following section immediately below the opening <configSections> element

<sectionGroup name="ESBProcessor">
  <section name="Resolver" type="System.Configuration.DictionarySectionHandler, System,Version=2.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
  <section name="AdapterProvider" type="System.Configuration.DictionarySectionHandler, System,Version=2.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
  <section name="ItineraryCache"  type="System.Configuration.DictionarySectionHandler, System,Version=2.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
  <section name="Cache" type="System.Configuration.DictionarySectionHandler, System,Version=2.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</sectionGroup>

- Add the following section at the end of the Machine.config file, immediately above the closing </configuration> element.

<ESBProcessor>
  <Resolver>
    <add key="UDDI"  value="Microsoft.Practices.ESB.Resolver.UDDI,  Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <add key="WSMEX" value="Microsoft.Practices.ESB.Resolver.WSMEX,  Version=1.0.0.0, Culture=neutral,  PublicKeyToken=31bf3856ad364e35" />
    <add key="XPATH" value="Microsoft.Practices.ESB.Resolver.XPATH, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <add key="STATIC" value="Microsoft.Practices.ESB.Resolver.STATIC, Version=1.0.0.0, Culture=neutral,  PublicKeyToken=31bf3856ad364e35" />
    <add key="BRE"  value="Microsoft.Practices.ESB.Resolver.BRE, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </Resolver>
  <AdapterProvider>
    <add key="WCF-WSHttp" value="Microsoft.Practices.ESB.Adapter.WcfWSHttp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <add key="WCF-BasicHttp" value="Microsoft.Practices.ESB.Adapter.WcfBasicHttp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <add key="FTP"  value="Microsoft.Practices.ESB.Adapter.FTP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <add key="FILE"  value="Microsoft.Practices.ESB.Adapter.FILE, ersion=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <add key="MQSeries" value="Microsoft.Practices.ESB.Adapter.MQSeries, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </AdapterProvider>
  <ItineraryCache>
    <add key="timeout" value="120" />
  </ItineraryCache>
  <Cache>
    <add key="UDDI" value="600" />
    <add key="WSMEX" value="600" />
  </Cache>
</ESBProcessor>

Install the ESB Management Portal and Associated Services:

- Make sure you build the portal website located at C:\Projects\Microsoft.Practices.ESB\Source\Samples\Management Portal\ESB.Portal
If the DundasWebChart component cannot be found, you're probably have a newer version than in the references.
The references look for v5.5.0.1697 and the latest from Dundas is v6.0.0.1724.
Remove the reference and add the new one which can be found in C:\Program Files\Dundas Software\Charting\WebControlVS2005\bin, then build the portal again.

- Create the ESBAdmin database by running the script located at C:\Projects\Microsoft.Practices.ESB\Source\Samples\Management Portal\SQL\ESB.Administration Database.sql

Create a new Virtual Directory for the ESBPortal:
- Alias: ESB.Portal
- Directory: C:\Projects\Microsoft.Practices.ESB\Source\Samples\Management Portal\ESB.Portal
- Allow the following: Read, Run Scripts (such as ASP)
- Allow anonymous access: No (enable Integrated Windows Authentication)
- Application Pool: ESBNetworkAppPool (Application pool is created in an earlier stage by PreProcessingCORE.vbs)
- Make sure ASP.NET 2.0 is selected for the virtual directory of the portal.

- Open web.config of the portal on C:\Projects\Microsoft.Practices.ESB\Source\Samples\Management Portal\ESB.Portal\web.config to check the connectionstring settings for "AdminDatabaseServer"(=ESBAdmin) and "EsbExceptionDb"
- Rebuild the portal

Check the portal settings:
- Start http://localhost/ESB.Portal
- If you get a login dialog, check if the "Integrated Windows Authentication" is on
Otherwise check web.config if the "authorization" section is allowing you access.

Install the ESB Management Portal Alert Service:
- Open the solution C:\Projects\Microsoft.Practices.ESB\Source\Samples\Management Portal\ESB.AlertService\ESB.AlertService.sln
- Open App.config and check if the connectionstring points to the correct "EsbExceptionDb" database
- Set the buildtype to 'Release'
- Build the solution to make sure also the setup project gets build
- Run the setup.exe created in C:\Projects\Microsoft.Practices.ESB\Source\Samples\Management Portal\ESB.AlertService.Install\Release
- Use default settings until a dialog shows up for credentials
- Select an account that is a member of the BizTalk Application Users group with access to both the EsbExceptionDb database and the server hosting the alert service.
- Enter the account name in the form: <DomainName>\<UserName>, if it is a local account use <servername>\<username>
- You can configure the settings using the portal (Admin -> Fault Settings)
- A service named "BizTalk ESB Exception Notification" is created, make sure it is set to start automatically and start the service

Install the ESB Management Portal UDDI Publishing Service:
- Open the solution C:\Projects\Microsoft.Practices.ESB\Source\Samples\Management Portal\ESB.UDDI.PublisherService\ESB.UDDI.PublisherService.sln
- Open App.config
- Check if the ConnectionStrings point to the correct "EsbExceptionDb" and "AdminDatabaseServer"(=ESBAdmin) database
- Check if the ApplicationSettings contain the correct ESB UDDI and BiztalkOperationService webservice addresses
- Add the following to the app.config and change them if necessary

<appSettings>
  <add key="uddiServerUrl" value="
http://localhost/uddi%22/>
  <add key="smtpServerAddress" value="smtpservername.yourdomain.com"/>
  <add key="emailNotificationFrom" value="
mailto:uddiservice@yourdomain.com%22/>
  <add key="defaultModelName" value="microsoft-com:esb:runtimeresolution"/>
  <add key="serviceInterval" value="30000"/>
  <add key="DomainName" value="YD"/>
</appSettings>

- Set the buildtype to 'Release'
- Build the solution to make sure also the setup project gets build
- Run the setup.exe created in C:\Projects\Microsoft.Practices.ESB\Source\Samples\Management Portal\ESB.UDDI.PublisherService.Install\Release
- Use default settings until a dialog shows up for credentials for the service account for the UDDI Publishing Service.
- Select an account that is a member of the BizTalk Application Users group with access and that has access to the server hosting the UDDI Publisher Service
- Enter the account name in the form: <DomainName>\<UserName>, if it is a local account use <servername>\<username>
- You can configure the settings using the portal (Admin -> Registry Settings)
- A service named "BizTalk ESB UDDI Publishing" is created, make sure it is set to start automatically and start the service

Configure Exception Management InfoPath Form Template Shares:
- Share the folder: C:\Projects\Microsoft.Practices.ESB\Source\Exception Handling\Source\ESB.ExceptionHandling.InfoPath.Reporting\Publish
- Set "Read" permissions for everyone
- Share the folder C:\Projects\Microsoft.Practices.ESB\Source\Samples\Exception Handling\Source\ESB.ExceptionHandling.InfoPath.Resubmit\Publish
- Set the name to "PublishResubmit" and "Read" permissions for everyone

* Ready with installation!!

Now you can start installing samples and play arround.

with 1 comment(s)
Filed under:

While looking for something totally different, I found this very informational poster.
It shows the various scale-out options for Biztalk Server 2006 R2, not in text but in very clear pictures.
I assume the scale-out options are also valid for regular 2006 installations.

In Microsofts own words:

"The BizTalk Server 2006 R2 Scale-Out Configurations poster shows typical scenarios and commonly used options for scaling out BizTalk Server physical configurations. The poster illustrates how to scale out BizTalk Server configurations to achieve high availability through load balancing and fault tolerance and how to configure for high-throughput scenarios. The poster is intended for use by IT professionals and developers who need to design, deploy, and manage large-scale implementations of BizTalk Server 2006 R2."

You can download the poster here.

To make the post complete, here some other posters. :-)


 

with no comments
Filed under:

Yesterday I finally did the 70-235 exam, "Developing Business Process and Integration Solutions Using Microsoft BizTalk Server 2006" and I passed it!

Now I'm officially a MCTS for Biztalk Server 2006! :-)

In the days before the exam I read some blogs from other people who did the exam and they are right about the content. About 50% of the questions are about the BRE and BAM, so if you're planning to take the exam make sure your knowledge is up-to-date about these two subjects.

As always they ask some code related questions and I saw some new type of questions in which you have to select actions and put them in the correct order.

 

with 2 comment(s)
Filed under:

This weekend I ran into some strange behaviour.
I have an orchestration in which I do the following:

  • Write a record in a database
  • Read the ID of the record
  • Send an email with that ID
  • Wait for a reply
  • Update the record in the database

It took me some time to get the record in the database and return the ID. There is a small note in the tutorial which says to use FOR XML RAW in case only one or two rows are returned.
To read the ID from the response message, I took the xpath query Biztalk shows in the schema editor and put it in an expression shape.

After putting in some trace logging I tested the orchestration. What I saw was that the record was correctly inserted in the database and the record ID was returned in the response message (I put in a send shape to verify what I got returned from the SQL adapter).

In the Debugview tool I noticed that the ID wasn't extracted correctly from the response and that the orchestration halted just before the 'Send email' part. Also in the eventlog I saw the following error message: Input string was not in a correct format. This error would mean I tried to convert a NULL value, but I didn't use any convert in the expression. Probably it was done implicitly caused by the incorrect xpath query.

To figure out where the orchestration exactly halted, I launched the orchestration debugger. I was very surprised to find out that the orchestration debugger told me it stopped on the receive shape from the SQL adapter, while I had an output message on the send shape just after that receive!!

I couldn't figure out why the logging showed me that the orchestration ran further than the orchestration debugger showed.

I tried all kinds of xpath queries and I found the correct one.
After updating my expression shape with the correct xpath, the orchestration finally ran as expected.

 

with no comments
Filed under:

For a customer I had a very simple Biztalk task: call a webservice from an orchestration.

The thing was that the webservice was secured using SSL, but Biztalk normally detects that and everything works fine.
However, in this case the SSL certificate was untrusted because it is a test environment.
I created a .NET client to test the webservice and I had to install the certificate as trusted in order to get it to work.
The Biztalk application refused to work and showed the following exception:

Error details: WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. AuthenticationException: The remote certificate is invalid according to the validation procedure.

After a long search Tomas Restrepo pointed me in the right direction.
The solution was very simple, just add the certificate also in the user store of the user the Biztalk services are running under.

with no comments
Filed under:

While setting up a default environment for WCF development, I thought it would be a good idea to also include something about fault contracts. A fault contract is an exception class the service can throw to the client containing specific exception information.

The steps to set this up on the service:

  • Create a class 
    • follow naming conventions like ending with 'FaultContract' like 'DefaultFaultContract'
    • add one or more properties to the class
  • Apply the FaultContract attribute in the interface to the requested method
    • [FaultContract(typeof(DefaultFaultContract))]
  • Throw the exception in the implementation
    • throw new FaultException<DefaultFaultContract>(new DefaultFaultContract("Something went wrong"));
    • you can also add a FaultReason to inform the client about the circumstances

After the service is build, the client can be generated using the 'Add service reference', but that won't be something new ;-)
Now the custom exception class is also known on the client and can be caugth with:

  • catch (FaultException<SampleService.DefaultFaultContract> ex)
  • in ex.Detail you can find your custom fault contract

In Visual Studio it is possible to let the debugger break on unhandled exception. Normally something you want to happen, but in this case it is not a good idea. The debugger thinks that the exception thrown in the service is unhandled, so it breaks saying it found an 'FaultException was unhandled by user code' but in fact the exception is handled by the client.

with 2 comment(s)
Filed under:
More Posts Next page »