dinsdag 18 december 2012

BizTalk deployment - How do YOU do it?



For the deployment of BizTalk applications we use a custom made tool within my company Cnext. Now I was curious to have some feedback from the community on the deployment of BizTalk applications. How do you handle the biztalk deployments at your company?

Our deployment manager tool is based on the idea to store all used objects in a database model (BizTalk artifacts, but also stuff like MSMQ, file locations, SQL objects, etc. …). Most of these objects are added using auto discovery of the BizTalk databases, so manually adding of objects is reduced to a minimum. Above all, BizTalk artifacts can have a different configuration (binding) defined per environment (test, dev, prod, …).
It also allows you to define all dependencies. Again most of these dependencies will be defined by the tool automatically.

This way of working makes it possible for the tool to define which actions need to be taken to deploy a certain application (or just a part of the application or only some objects). The deployment manager tool will define which objects need to be removed and redeployed (also unenlisting/disabling en starting/enabling artifacts will be done by itself). As a result, using the tool will allow us to deploy much faster, because the objects to redeploy are reduced to an absolute minimum and no complete redeploy is needed (like BizTalk Deployment framework does for example).

Another very useful and much used functionality is the possibility to define complete business/functional flows, including some generic components. This makes sure you can also deploy or redeploy a complete (new) flow (like an order flow for example) by itself, including all necessary objects (as well receive as send ports, file locations, etc. …).

The deployment can be done cross BizTalk applications. So the separation in applications is no longer deployment dependent.

The most important part is to set the database model correct and keep it this way… this will guarantee a much easier and faster deployment, where each environment has its own version of the current deployed objects.

Please answer following questions:

  1.      Is your BizTalk deployment automated (BizTalk deployment framework, custom scripting with MSBuild or BTSTask, powershell scripts, etc. …), or do you just do manual deployment using MSI and binding files?
  2.        Which deployment tools or scripts are you using, or have you used before? And what are your thoughts of these tools (benefits and complaints)?
  3.        What do you think of a tool like our custom deployment manager tool (using autodiscovery, etc. …)?


Thanks for your replies.
 When there is enough feedback, I'll devote a new post on my analysis.



woensdag 28 november 2012

SQL Server Configuration Manager - Error 0x80041010

When opening the SQL Server Configuration manager (for SQL Server 2008 R2 in my case), I kept getting following error:

Cannot connect to WMI provider. You do not have permission or the server is unreachable. Note that you can only manage SQL Server 2005 and later servers with SQL Server Configuration Manager. Invalid class [0x80041010]


The solution to resolve this turned out to be quite simple. Just open a command prompt and execute following command:

C:\Program Files\Microsoft SQL Server\100\Shared>mofcomp "C:\Program Files\Microsoft SQL Server\100\Shared\sqlmgmproviderxpsp2up.mof"

Depending on the SQL version installed the path to the file could also be something like C:\Program Files\Microsoft SQL Server\90\Shared\sqlmgmproviderxpsp2up.mof

woensdag 14 november 2012

Blog admin of my companies blog

First of all, I would like to thank all of my regular reader and hope you've al enjoyed my blog posts for almost 2 years now. I already announced in one of my previous posts some time ago that I would join the contributors of the biztalk admin blog at http://www.biztalkadminsblogging.com/ .

Today, I'm proud to announce that there is another brand new blog I will be contributing to on BizTalk and Azure related news, problem solvement, etc.... My companies (Cnext) blog (http://blog.cnext.eu) . Well actually, the blog already existed quite some time (even longer than my own blog :) ), but there wasn't any new posts for over 2 years. Most recently I became the new administrator of the Cnext blog and had the task to revive it. After 1 month, 3 completely new posts, and still some blog posts in the making, it is ready to be shared with all of you... see for yourself at the Cnexts revived blog.

The first thing I did is restyle the entire blog to match the current branding of Cnext. And after publishing some new material, I can say that it is ready to be read!

Now go and check it out.. and keep following all of my blog posts.




More info on cnext can be found on http://www.cnext.eu. And as mentioned the blog will be situated at http://blog.cnext.eu... keep an eye out for all new material to be added soon!

woensdag 7 november 2012

Biztalk 2013 Beta released

Microsoft finally released a beta version of the new biztalk, wich can be found here.
The first thing that should be noticed is that Microsoft decided to change the next versions name from Biztalk 2010R2 to Biztalk 2013. This has some very important consequences… It indicates the next version to be a major release, which implies a much longer support from Microsoft.
Microsoft’s support lifecycle policy says that products will have 5+5 years (mainstream+extended) support. However, that applies to major versions. If the product would still be BizTalk Server 2010 R2, it will not get an extended support lifecycle end date.

So in conclusion, having the next Biztalk version being a full release is an important sign to the market, it implies a much longer support lifecycle for the product.


Biztalk 2013 will have following new features:

  • Integration with Cloud Services: messages using different relay endpoints hosted on Azure.

  • RESTful services: provides adapters to invoke REST endpoints as well as expose BizTalk Server artifacts as a RESTful service.

  • Enhanced SharePoint adapter: the need for dependency on SharePoint farms has been removed, while still providing backward compatibility.

  • SFTP adapter: added an SFTP adapter that will enable sending and receiving messages from an SFTP server.

  • ESB Toolkit integration: ESB Toolkit is now fully integrated with BizTalk Server. Also, the ESB Toolkit configuration experience is vastly simplified to enable a quick setup.

  • Dependency tracking: dependencies between artifacts can now be viewed and navigated in Admin console.

  • Improvements in dynamic send ports: the ability to set host handler per adapter, instead of always using the default send handler of the adapters.

woensdag 24 oktober 2012

Exception handling in BizTalk orchestrations explained

When creating BizTalk orchestrations, we also have some building blocks available to do exception handling. In this blog I'll try to give a very brief explanation of the available building blocks for your orchestration. I won't describe everything in detail, because this would lead us to far (and would give one massive blog post).

For exception handling in orchestration there are 3 shapes available:
  • Throw Exception
  • Scope
  • Compensate

I want go in much details for the Scope and Compensate shapes. If you need more detailed description on how Exception handling can be used with these 2 shapes I would suggest reading this blog from Richard Seroter. And if this still doens't answers all of your questions, let me know... than I can devote another post with a more detailed explanation on some aspects of the exception handling in orchestrations.

Throw Exception

Firstly we have the 'Throw Exception'-shape. this one is the simplest of all shapes for exception handling.
Frankly, it does nothing more than it's name suggests... It just throws an Exception, nothing more fancy. To achieve this you'll need to follow these three simple steps:
  1. Define a variable with the type set to any Exception class you prefer. In below example I've created an exception variable of type Microsoft.Biztalk.Message.Interop.BTSException


  2. Note: The Report To Analyst property in the screenshot exists on many shapes. The property however has no influence on the behavior of your orchestration. I merely is a property used to integrate withe the Orchestration Designer for Business Analysts (ODBA) Visio plugin. If set to false, that shape will be considered as a low level detail that won't be visible in the Visio Designer.

  3. Instantiate the variable and set any values according to the occured error
  4. Now use the Throw Exception shape and configure it ro use the Exception object you've created



Scope

Scopes are used for three reasons
  1. to configure transaction (long running or atomic)
  2. to handle exceptions
  3. to trigger compensating logic
For more info on the transaction types, I'll refer to this blog from Sandro Pereira.

A scope shape can have one or more Exception handling blocks and/or one Compensation Block. The Transaction type you've chosen for your scope will define which of these blocks can be added. An atomic scope can only have a compensation block, and a scope configured with the transaction type non can only have an Exception block. While a long running scope can have both blocks.
For an overview of the possibilities, check the below screenshot.

Note that there could be more than one Exception block, but only one Compensation block added to a Scope

Exception handling block

The Exception handling block is used to catch exceptions that occur inside the scope the block belongs to. The Exception Object Type in the properties of the exception block will define which Exceptions types will be handled by this Exception block.


When an exception occurs, the engine will check for the closest exception block that can handle this type of exception. The consideration of which exception block will be called is determined sequentially, just like in .NET. If no suitable exception handler is found, the default exception handles is triggered, and this means that the compensation blocks for all nested scopes will be called, after which the exception is rethrowed and the orchestration will become suspended.

Compensation block

Compensation is a way to correct or undo logical piece of work that have previously committed. An exception can occur in the orchestration afther succesfully executing all logic in the scope. In this case, the process might be in a state where it is logically incorrect. So the action already performed in a transactional scope need to be compensated... this can be achieved using a compensation block
If no compensation block is added, the default compensation will be performed. this means calling all compensation blocks of the nested scopes, starting with the most recently completed ones, just as with the default exception handler.

Compensate

The compensate shape can only be used inside of an exception handler. The explicit use of this compensate shape, allows us to specify the order of compensation execution ourselfs. So this can be used in cases the default order (starting from te most recently completed ones and working its way back) doesn't fit.
1 compensate shape can only trigger 1 compensation block of a transaction. So the order must be defined using multiple compensate shapes, calling the compensation blocks in the desired order.



Remarks

  • Keep in mind that the default Exception handler, if triggered, will initiate the compensation by calling all compensation blocks for the nested scopes. Compensation blocks of the nested scopes will be called starting with the most recently completed scope and work its way back.

    But whenever you catch an exception using the Exception handler block, then you must explicitly do the compensation.


  • If no custom compensation block has been added, the default compensation will be performed. Just like with the exception handler, this will call the compensation blocks of any nested scopes starting with the most recently completed scope.


  • A Compensate shape can only be used inside an Exception handling block or another Comensation Block. When calling the compensate of the current scope, the default compensatino handler will be triggered instead of the compensation code defined by the compensation block.

woensdag 17 oktober 2012

Error on attaching DB

When trying to reattach a database I kept getting following error:

In the SQL log I could find below error. The same error was given when trying to attach the DB with a T-SQL statement.

Msg 5120, Level 16, State 101, Line 3 Unable to open the physical file "E:\Program Files\Microsoft SQL Server\MSSQL10_50.BTSISDEV1\MSSQL\DATA\BizTalkMsgBoxDb.mdf". Operating system error 5: "5(failed to retrieve text for this error. Reason: 15105)".

After several attempts on how to solve this I finally found the solution.
Turned out, all I needed to do was run the SQL Server Management Studio as an Administrator.
How can it be that simple, yet has me looking for a solution for over an hour :).

dinsdag 9 oktober 2012

BizTalk: using macros in file names

BizTalk allows you to use several macros for defining a file name in a biztalk send port.

The following table lists the supported macros and describes how the File send handler replaces them.

Macro name Substitute value
%datetime%Coordinated Universal Time (UTC) date time in the format YYYY-MM-DDThhmmss (for example, 1997-07-12T103508).
%datetime_bts2000%UTC date time in the format YYYYMMDDhhmmsss, where sss means seconds and milliseconds (for example, 199707121035234 means 1997/07/12, 10:35:23 and 400 milliseconds).
%datetime.tz%Local date time plus time zone from GMT in the format YYYY-MM-DDThhmmssTZD, (for example, 1997-07-12T103508+800).
%DestinationParty%Name of the destination party. The value comes from the message context property BTS.DestinationParty.
%DestinationPartyQualifier%Qualifier of the destination party. The value comes from the message context property BTS.DestinationPartyQualifier.
%MessageID%Globally unique identifier (GUID) of the message in BizTalk Server. The value comes directly from the message context property BTS.MessageID.
%SourceFileName%Name of the file from which the File adapter read the message. The file name includes the extension and excludes the file path, for example, Sample.xml. When substituting this property, the File adapter extracts the file name from the absolute file path stored in the FILE.ReceivedFileName context property. If the context property does not have a value—for example, if a message was received on an adapter other than the File adapter—the macro will not be substituted and will remain in the file name as is (for example, C:\Drop\%SourceFileName%).
Aa578022.note(en-us,BTS.20).gifNote
Correct implementation of this macro requires that the output message is the same message as the received message.
%SourceParty%Name of the source party from which the File adapter received the message.
Aa578022.note(en-us,BTS.20).gifNote
Correct implementation of this macro requires that the output message is the same message as the received message.
%SourcePartyQualifier%Qualifier of the source party from which the File adapter received the message.
Aa578022.note(en-us,BTS.20).gifNote
Correct implementation of this macro requires that the output message is the same message as the received message.
%time%UTC time in the format hhmmss.
%time.tz%Local time plus time zone from GMT in the format hhmmssTZD (for example, 124525+530).

NOTE

The File send handler does not replace the macros with a value if any of the following are true:
  • The corresponding system property is not set.
  • The macro is misspelled.
  • The value for the macro contains symbols that are not valid in the file name.

Using Macros in SMTP Headers

There are however some restrictions when using the macros in SMTP headers.
See this post for more details on this matter.

Below is a short overview of the use of macros in SMTP headers.

Macro Description For use with To For use with CC For use with Subject
%MessageID%Globally unique identifier (GUID) of the message in BizTalk Server. The value comes from the message context property BTS.MessageID.NoNoYes
%datetime_bts2000%UTC date time in the format YYYYMMDDhhmmsss, where sss means seconds and milliseconds (for example, 199707121035234 means 1997/07/12, 10:35:23 and 400 milliseconds).NoNoYes
%datetime%UTC date time in the format YYYY-MM-DDThhmmss (for example, 1997-07-12T103508).NoNoYes
%datetime.tz%Local date time plus time zone from GMT in the format YYYY-MM-DDThhmmssTZD, (for example, 1997-07-12T103508+800).NoNoYes
%time%UTC time in the format hhmmss.NoNoYes
%time.tz%Local time plus time zone from GMT in the format hhmmssTZD (for example, 124525+530).NoNoYes
%SourceParty%Name of the source party from which the File adapter received the message.NoNoYes
%SourcePartyQualifier%Qualifier of the source party from which the File adapter received the message.NoNoYes
%DestinationParty%Name of the destination party. The value comes from the message context property BTS.DestinationParty.YesYesYes
%DestinationPartyQualifier%Qualifier of the destination party. The value comes from the message context property BTS.DestinationPartyQualifier.NoNoYes


Source: http://msdn.microsoft.com/en-us/library/aa578022(v=bts.20).aspx

woensdag 19 september 2012

Optimize your SQL statements

It is always good practise to optimize your SQL query statements for a better performance. Just making sure your query does what it needs to, isn't enough. You should consider the performance impact of your code and try to optimize it for the best performance.

Below is a short list of steps to take when optimizing your query statements.
More details on the steps can be found in this blog.

  1. Check if you're missing any required table joins.
    This could result in a Cartesian join.

  2. Check if you're missing any required WHERE clause to prevent retrieving too much data.

  3. Check if statistics are being created & updated automatically.

  4. Check if the statistics are up-to-date.
    The DBCC SHOW_STATISTICS command can be used to view the last updated date-time, total table rows and the number of rows sampled.
    Outdated statistics can be renewed using  the sp_updatestats stored procedure, or By using the FULLSCAN option to update all statistics of a table.

  5. Check for any missing table or Index scans by using the execution plans.
    you can use these DMV's to check for missing indexes: sys.dm_db_missing_index_details, sys.dm_db_missing_index_group_stats, sys.dm_db_missing_index_groups.

  6. Check for RID Lookups, also by using the execution plans.
    These cannot always be eliminated, but by making use of covering indexes, RID Lookups can be reduced.

  7. Check for any sort operator, again by using the execution plans.
    There are 3 options:
    • Modify the underlining tables to create a CLUSTERED index on the required sort columns. It could be worth trying out creating the CLUSTERED index on another column which is not the Primary Key.
    • Create an Indexed view on the underlining tables and sort the view by creating a CLUSTERED Index.
    • Create a NON CLUSTERED Index on the specified columns and Include all other columns which will be returned.


  8. Check for excessive index fragmentation.
    The DMV sys.dm_db_index_physical_stats can be used for this matter.

  9. Check table locks.
    To prevent locking problems, follow these guidelines:
    • Keep transactions as short as possible.
    • Review the transaction isolation level, and consider minimizing locking contention, thus increasing concurrency by changing to 'Read Committed using row versioning' or 'Snapshot'.
    • Specify table hints such as READUNCOMMITTED or READPAST on the select statements. Although both of these table hints do increase concurrency, both have disadvantages such as 'dirty reads' when using the READUNCOMMITTED or returning an incomplete data set when using the READPAST and therefore they may not be acceptable to use in all circumstances.


Source: http://www.sqlservercentral.com/articles/Performance+Tuning/70647/

Speeding Up Database Access

I found a complete serie on speeding up acces to your SQL Database.

So far, there are only 4 parts published of an 8 part series of articles on speeding up access to a SQL Server Database.
Here's an overview of the content of all 8 parts (including links of already published parts):

  • Part 1 Pinpointing missing indexes and expensive queries
    • Find expensive queries (with trace log)
    • Locate missing indexes with the query optimizer (or with Tuning Advisor)
    • Find unused indexes
  • Part 2 Pinpointing other bottlenecks
    • Find Locks and Latches (via counters in perfmon)
    • Execution plan reusability (using counters or dynamic management views (DMV))
    • Fragmentation of data and indexes
    • Memory check (using counters to verify if there’s a lack of memory)
    • Disk usage (locate possible disk bottlenecks using counters)
    • CPU (use counters to see if the CPU is stressed)
  • Part 3 Fixing missing indexes
    • Indexes explained (clustered and nonclustered indexes)
    • Index usage (when / when not)
    • Maintaining indexes
  • Part 4 Fixing expensive queries
    • Cache aggregation queries
    • Keep records short
    • Considering Denormalization
    • Be careful with triggers
    • Use table variables for small temporary result sets
    • Use Full Text Search instead of LIKE
    • Replacing cursors with set based code
    • Minimise traffic from SQL Server to Web Server
    • Object Naming
    • Use SET NOCOUNT ON
    • Use FILESTREAM for values over 1MB
    • Avoid functions on columns in WHERE clauses
    • Use UNION ALL instead of UNION
    • Use EXISTS instead of COUNT to find existence of records
    • Combine SELECT and UPDATE
  • Part 5 Fixing locking issues
  • Part 6 Fixing execution plan reuse
  • Part 7 Fixing fragmentation
  • Part 8 Fixing memory, disk and CPU issues

I'll update this post when new parts are published.

woensdag 5 september 2012

Formatting code to HTML

I like to share a website I frequently use to format any code (C#, XML or T-SQL) to HTML for using on my blog. Other possibilities are to format VB, HTML or msh, but I haven't used these myself yet.
You can also add things like line numbers, or use alternating backgrounds. And to modify the colors of the output, you'll just need to change the css style sheet.

Also because everytime I need it, I'll have to search the website again on google. So this way I'll save some time for me too :).

Here's the link: http://www.manoli.net/csharpformat/

Delete BizTalk backup files

The SQL Server agent job "Backup BizTalk Server" will not delete the generated backup files automatically. The job does clear the backup history table in the database, but it will never delete the backup files from the disk. Which will of course result in the disk to fill up eventually and the backup job will fail from then on.

Here's a simple stored procedure to call from the "Backup BizTalk Server" job in the "Clear Backup History" step. Just follow these steps:
  1. Open SQL Server management Studio
  2. Open a new query window and connect to the BizTalkMgmtDb database
  3. Execute this script to add a new stored procedure called sp_DeleteBackupHistoryAndFiles
    USE [BizTalkMgmtDb]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER PROCEDURE [dbo].[sp_DeleteBackupHistoryAndFiles] @DaysToKeep smallint = null, @UseLocalTime bit = 0
    
    AS
     BEGIN
    
     set nocount on
    
      IF @DaysToKeep IS NULL OR @DaysToKeep <= 0
      RETURN
    
         /*
            Only delete full sets
            If a set spans a day such that some items fall into the deleted group and the other don't don't delete the set
    
            Delete history only if history of full Backup exists at a later point of time
            why: history of full backup is used in sp_BackupAllFull_Schedule to check if full backup of databases is required or not.
            If history of full backup is not present, job will take a full backup irrespective of other options (frequency, Backup hour)
        
        */
            
      declare @PurgeDateTime datetime
    
      if (@UseLocalTime = 0)
        set @PurgeDateTime = DATEADD(dd, -@DaysToKeep, GETUTCDATE())
      else
        set @PurgeDateTime = DATEADD(dd, -@DaysToKeep, GETDATE())
    
      DECLARE DeleteBackupFiles CURSOR
    
      FOR SELECT 'del "' + [BackupFileLocation] +  case right(BackupFileLocation,1) when '\' then '' else '\' end + [BackupFileName] + '"' FROM [adm_BackupHistory] [h1]
        WHERE     [BackupDateTime] < @PurgeDateTime
        AND    [BackupSetId] NOT IN ( SELECT [BackupSetId] FROM [dbo].[adm_BackupHistory] [h2] WHERE [h2].[BackupSetId] = [h1].[BackupSetId] AND [h2].[BackupDateTime] >= @PurgeDateTime)
        AND EXISTS( SELECT TOP 1 1 FROM [dbo].[adm_BackupHistory] [h2] WHERE [h2].[BackupSetId] > [h1].[BackupSetId] AND [h2].[BackupType] = 'db')
    
      DECLARE @cmd varchar(400)
    
      OPEN DeleteBackupFiles
    
       FETCH NEXT FROM DeleteBackupFiles INTO @cmd
    
      WHILE (@@fetch_status <> -1)
      BEGIN
                IF (@@fetch_status <> -2)
                BEGIN
    
                            EXEC master.dbo.xp_cmdshell @cmd, NO_OUTPUT
    
                            delete from [adm_BackupHistory] WHERE CURRENT OF DeleteBackupFiles
    
                            print @cmd
                END
    
                FETCH NEXT FROM DeleteBackupFiles INTO @cmd
      END
    
      CLOSE DeleteBackupFiles
    
      DEALLOCATE DeleteBackupFiles
    
      END
    
  4. 5.Modify the "Clear Backup History" step of the Backup BizTalk Server job to call sp_DeleteBackupHistoryAndFiles, instead of calling the stored procedure sp_DeleteBackupHistory
  5. Make sure xp_cmdshell for the SQL Server instance is enabled. this will be disabled by default. To enable this, execute following SQL script:
    EXEC master.dbo.sp_configure 'show advanced options', 1
    
    RECONFIGURE
    
    EXEC master.dbo.sp_configure 'xp_cmdshell', 1
    
    RECONFIGURE
    
    


This stored procedure is made for BizTalk Server 2010.
Because with the release of BizTalk 2010 there have been changes to the sp_DeleteBackupHistory stored procedures. They added a parameter to the stored procedure to use local time and changed the query to prevent the deletion of the history from the last full backup set forward.

For older versions of BizTalk you should use this script instead:
CREATE PROCEDURE [dbo].[sp_DeleteBackupHistoryAndFiles] @DaysToKeep smallint = null
AS
BEGIN
set nocount on
  IF @DaysToKeep IS NULL OR @DaysToKeep <= 0
  RETURN
/*
  Only delete full sets
  If a set spans a day such that some items fall into the deleted group and the other doesn't, do not delete the set
*/ 

DECLARE DeleteBackupFiles CURSOR
FOR SELECT 'del "' + [BackupFileLocation] + '\' + [BackupFileName] + '"' FROM [adm_BackupHistory]
WHERE  datediff( dd, [BackupDateTime], getdate() ) >= @DaysToKeep
AND [BackupSetId] NOT IN ( SELECT [BackupSetId] FROM [dbo].[adm_BackupHistory] [h2] WHERE [h2].[BackupSetId] = [BackupSetId] AND datediff( dd, [h2].[BackupDateTime], getdate() ) < @DaysToKeep )
DECLARE @cmd varchar(400)
OPEN DeleteBackupFiles
FETCH NEXT FROM DeleteBackupFiles INTO @cmd
WHILE (@@fetch_status <> -1)
BEGIN 

            IF (@@fetch_status <> -2)
            BEGIN
                        EXEC master.dbo.xp_cmdshell @cmd, NO_OUTPUT
                        delete from [adm_BackupHistory] WHERE CURRENT OF DeleteBackupFiles
                        print @cmd
            END 

            FETCH NEXT FROM DeleteBackupFiles INTO @cmd
END 

CLOSE DeleteBackupFiles
DEALLOCATE DeleteBackupFiles
  END
GO



Source: http://www.biztalkbill.com/Home/tabid/40/EntryId/81/Update-to-Stored-Procedure-to-delete-Backup-BizTalk-Server-SQL-Agent-backup-files.aspx

vrijdag 31 augustus 2012

Using System Colors in C#

When choosing a color in the properties window in visual studio, there is the possibility to choose from so called System Colors. An example for this is the color 'Window', which is the default for a textbox.
Now, I tried to set the BackColor of a Textbox programmatically back to this system color 'Window'. Turned out not to be as easy as I thought it would be.

I tried things like Color.? ... I hoped to find the color in this namespace, or even a System subsection for the systemcolors. Nothing to be found however.
Nor was there any namespace like System.Color to be found.

But how can these system colors be set from C# code than?

Well, one way turned to be using this command:

System.Drawing.Color.FromKnownColor(KnownColor.Window)

And, as you'd expect, the KnownColor enumeration contains all of the other user-definable colors.

Or even an easier method to achieve this is

System.Drawing.SystemColors.Window

donderdag 16 augustus 2012

SQL Fragmentation explained

Found an interesting article on fragmentation in SQL.

It explains the two types of fragmentation that can occur, namely internal and external fragmentation.
Internal fragmentation means that the pages are not completely full. While external fragmentation refers to the lack of correlation between the logical sequence of an index and its physical sequence.

For more details I'll refer to this excellent blog post.

Source: Stairway to SQL Server Indexes: Level 11, Index Fragmentation - SQLServerCentral

donderdag 19 juli 2012

Difference between 2 dates in C#

I tried to do a simple DateTime calculation in C#. What I wanted to achieve is to know how many years, months and days where between 2 DateTime variables. Or at least I thought this would be easy. Turns out there is know real out-of-the-box functionality available to handle this in C#.

The only thing available out-of-the-box in C# is using TimeSpan. Unfortuanately the only calculations TimeSpan can return is the number of days, hours, minutes, seconds and milliseconds. But how about the years, months and days than?

Here's a simple method to show the possibilities of the TimeSpan:
public void PrintDateDiffUsingTimeSpan(DateTime begin, DateTime end)
        {
            TimeSpan span = end - begin;

            StringBuilder str = new StringBuilder();
            str.Append("Total span: ");
            str.Append(span.Days + " days, ");
            str.Append(span.Hours + " hours, ");
            str.Append(span.Minutes + " minutes, ");
            str.Append(span.Seconds + " seconds, ");
            str.Append(span.Milliseconds + " milliseconds");

            Console.WriteLine(str.ToString() + "\n");


            Console.WriteLine("Total Days: " + span.TotalDays);
            Console.WriteLine("Total Hours: " + span.TotalHours);
            Console.WriteLine("Total Minutes: " + span.TotalMinutes);
            Console.WriteLine("Total Seconds: " + span.TotalSeconds);
            Console.WriteLine("Total Milliseconds: " + span.TotalMilliseconds);
        }

I ended up using a freely available .NET library called 'Time Period'. The source code can be found here. There's also an on line demo and documentation available.
Here's a simple method to show some the possibilities of the TimeSpan:

  public void PrintDateDiff(DateTime begin, DateTime end)
        {
            DateDiff diff = new DateDiff(begin, end);
            
            StringBuilder str = new StringBuilder();
            str.Append("Total difference: ");
            str.Append(diff.ElapsedYears + " years, ");
            str.Append(diff.ElapsedMonths + " months, ");
            str.Append(diff.ElapsedDays + " days");

            Console.WriteLine(str.ToString() + "\n");

            Console.WriteLine("Total Days: " + diff.Days);
            Console.WriteLine("Total Weeks: " + diff.Weeks);
            Console.WriteLine("Total Weekdays: " + diff.Weekdays);
            Console.WriteLine("Total Quarters: " + diff.Quarters);
            Console.WriteLine("Total Hours: " + diff.Hours);
        }

There are much more possibilities in the DateDiff class of the Time Period library. There are even much more classes available in the library. To know more of the capabilities of this library I again refer to the documentation.

Source: http://www.itenso.com/en/

dinsdag 17 juli 2012

BizTalk Server Performance

Have you ever wanted to evaluate the performance of your Biztalk installation?
Evaluating your performance could be done by analyzing quite some counters in the performance monitor of Windows. Or maybe by using the Performance Analysis of Logs (PAL) Tool.

However I just found a recently released tool to benchmark your biztalk environments.
The tool is called blogical and can be found on codeplexe here.

How it works:
  1. After the user has started the application and specified the BizTalk Group, the tool analyzes its configuration, finding all the BizTalk servers, Messageboxes etc.
  2. Secondly, the user gets to select one of two scenarios: Messaging or Orchestration. Each scenario has a set of tested environments such as
    • “Single server (2*Quad CPU, 4GB RAM)”
    • “1*BTS (1*Quad CPU. 4GB RAM) + 1*SQL(1*Quad CPU, 8GB RAM)”.
    • “2*BTS (2*Quad CPU. 8GB RAM) + 2*SQL(2*Quad CPU, 16GB RAM)”.
  3. The user selects the environment which most resembles his/her own.
  4. The user then starts the Indigo Service, a console application hosting a service which will be called from the BizTalk Send port.
  5. As the user clicks “Run test”, the tool continues to start ports and orchestrations. It will also start the Perfmon collector sets if the user has chosen to create those.
  6. As the test proceeds the user can monitor the counter values through the gauges (CPU utilization, Received msgs/sec and Processed msgs/sec). The default test duration is 30 minutes, with a warm-up of 2 minutes.
  7. Finally, the user is presented a result, which is either Succeeded or Failed.

For more information:
Benchmark your BizTalk Server (Part 1)

How to install:
Benchmark your BizTalk Server (Part 2)

BBW Drill Down:
Benchmark your BizTalk Server (Part 3)

High Scores:
http://blogical.se/bbw


Another thing I wanted to share with you regarding performance of Biztalk installations is the Microsoft BizTalk Server 2009 Performance Optimization Guide .
This guide provides in-depth information for optimizing the performance of a BizTalk Server solution.

Also check BizTalk Health Check post on Technet Wiki. It's a list of checkpoints that should be covered when performing a health check

vrijdag 13 juli 2012

Promote using Correlation initialisation inside a loop

I assume you already know how to promote properties when sending a message from an orchestration to the messagebox.
This can of course be achieved by initializing a correlation set with containing all context properties you like to promote. But that 's not why I'm posting this blog. If you need more info on how to promote properties from an orchestration I'll refer you to this blog.

Problem

The problem is when you try to do this from a send shape inside a loop, you'll get an error when building the project in visual studio.
The received error is "Correlation set may be initialized only once".

Solution

The solution to this issue is actually real easy. All you have to do is create a scope inside the loop. And place the send shape (and even other shapes if needed) in the created orchestration. The benefit of the orchestration is that you can define the correlation set on the scope itself (instead of as a global correlation set).
Now can initialize your correlation set on your send shape inside the scope.

And that's all you'll have to do!! It really is that easy! :)

donderdag 12 juli 2012

Passed the Microsoft BizTalk Exam

As of yesterday I can call myself a Microsoft Certified Technology Specialist (MCTS): Microsoft BizTalk Server 2010.

I passed the exam 70-595: Developing Business Process and Integration Solutions by Using Microsoft BizTalk Server 2010. I did this making only a single mistake, not bad at all :).

All I did as preparation was reading the book (MCTS): Microsoft BizTalk Server 2010 (70-595) Certification Guide once. This together with the practical knowledge I had gathered on the job made sure I passed the exam easily.

So all credits go to the authors of the book (Johan Hedberg, Kent Weare , Morten la Cour). They definitely achieved their goal. Also the sample questions (and their answers) were very helpful in the preparation.

woensdag 13 juni 2012

Identify Performance Bottlenecks in BizTalk

I found a series of blogs on how to identify Performance bottlenecks in BizTalk Environments.
Also look at this article on finding and eliminating bottlenecks

Here's an short overview of all the steps, including a link to the more detailed explanation:

Step 1: Monitoring BizTalk Host Instances via Windows Performance Counters


 The first place to measure the BizTalk performance can be done using Performance Counters. These counters let you monitor all components like the message box, orchestrations, adapters, etc… .

Step 2: Analyzing BizTalk Adapters


A deeper look at the adapter performances, again using some performance counters.

Step 3: Analyze Pipelines


It is important to understand the impact of Pipeplines that are used. Because each of the pipelines have a significant impact on the overall BizTalk performance as they perform actions on every single message that gets through BizTalk
One way to analyze what is really going on in pipelines is using an Application Performance Management Solution with Transactional Tracing capabilities, like dynaTrace for example.

Step 4: Analyzing Orchestration


Orchestration can get quite complex sometimes, but how to analyze the performance of these orchestrations?

The actual logic behind the Orchestration Definition is compiled into an assembly, loaded into BizTalk, and gets executed when messages are processed by that Orchestration Definition. A more detailed overview of the execution of such an orchestration can be generated with PurePath for example.

Another way to analyze the orchestration performance can again be done using performance counters.  BizTalk provides a set of counters for the Orchestration Engine as well as for the MessageBox.

Step 5: Analyzing external service calls (SendPorts)


Often BizTalk Orchestration makes a call to an external web service. PurePath can also give you an idea of the time consumed for this external web service call.


FINAL NOTE


As a final note I would like to point out to use the MessageBox Viewer Tool. The tool gives an overview of what might be wrong in your installation.
This tool runs a set of tests and queries against the MessageBox database an creates a nice report. The result can be viewed using the tool or it can generate an HTML report.

dinsdag 12 juni 2012

Best practices on Biztalk Tracking

I announced in a previus post that I joined the blogging team on biztalkadminsblogging.com.
However it took untill today before my first blog post was created.

I gave it a long thought what my first blog post should cover. the result is a post on some best practices for the usage of tracking in BizTalk... hope you like it!

The actual post can be found here http://www.biztalkadminsblogging.com/index.php/item/83-best-practices-for-tracking

vrijdag 1 juni 2012

New blog site: Windows Azure Road trip

There is a brand new developers' blog site on Windows Azure, called windows azure roadtrip. three specialist developers, each in thier own programming language, will be posting some blogs regularly.

Maarten Balliauw (a .NET developer) kicked it off with the very first blog post 'Winsows Azure when you code .NET: what & Why'.
The other blog writers are Michelangelo van Dam (a PHP developer) and Fran├žois Hertay (a Java developer).

Keep a close eye on this webiste, more useful blog posts to come.

Resource: https://www.azure-roadtrip.be/


dinsdag 22 mei 2012

joined BizTalkAdminsBlogging.com

My personal blog only exists for a year and a half now, but already has quite some visitors. Yesterday I was even asked to join another Biztalk blogging team on Biztalk administrator related topics. I already knew the blog and was a frequent visitor of the website. Of course I was glad to join the Biztalk blog team.

So, as of  today I joined several other biztalk experts on the BizTalk admin blog BizTalkAdminsBlogging.com.
This blog is dedicated to provide BizTalk admins with useful information, tips, example scripts and everything else that is interesting for a BizTalk admin.

I will still publish posts to this blog, but I will also write an occasional blog post for the BizTalkAdminsBlogging.com website... My first post on the site still has to be written, and any suggestions are always welcome :).

My profile on BizTalkAdminsblogging.com: http://www.biztalkadminsblogging.com/index.php/component/k2/itemlist/user/59-mitchvanhelden

maandag 21 mei 2012

Guideline to Solve Performance issues of Biztalk

Typically a performance problem can be narrowed down to one of the following components of a BizTalk Server environment:
·         A receive adapter or the system from which the adapter is receiving documents. For example, if documents are being received by the HTTP adapter at a suboptimal rate then the problem may be with the HTTP receive adapter or with the client that is posting to the HTTP adapter.
·         An orchestration service instance.
·         Performance of the SQL Server that hosts the BizTalk Server databases.
·         A send adapter or the system that the adapter is sending documents to. For example, if documents are being sent by the SQL adapter at a suboptimal rate then the problem may be with the SQL send adapter or with the computer running SQL Server that the SQL adapter is updating.

Use the following guidelines to help identify the components of the BizTalk Server environment that are performing poorly:
·         Capture any warnings or errors generated in the BizTalk Server or SQL Server Event Viewer.
·         Follow the steps in "Identifying Performance Bottlenecks" in BizTalk Server Help at http://go.microsoft.com/fwlink/?LinkId=154238 to help identify performance bottlenecks.
Once the poorly performing component has been identified, follow the appropriate guidelines to help resolve the issue:
Guidelines for resolving performance problems related to send and receive adapters
·         For information about troubleshooting problems with BizTalk Server adapters, see "Troubleshooting BizTalk Server Adapters" in BizTalk Server Help at http://go.microsoft.com/fwlink/?LinkId=154240. This section contains general troubleshooting information including information about how to set up logging for certain adapters, and information that can be used diagnose network problems, problems with MSDTC, problems with the registry, problems with the file system, and problems with IIS.
·         For information about troubleshooting problems with MSDTC, certificates, Enterprise Single Sign-On, and SQL Server, see the appropriate section of "Troubleshooting BizTalk Server Dependencies" in BizTalk Server Help at http://go.microsoft.com/fwlink/?LinkId=154242.
Guidelines for resolving performance problems related to orchestrations
·         For information about modifying the appropriate sections of the BTSNTSvc.exe.config file, see "Orchestration Engine Configuration" in BizTalk Server Help at http://go.microsoft.com/fwlink/?LinkId=154244.
Guidelines for resolving performance problems related to SQL Server
·         SQL Server Profiler can be used to capture Transact-SQL statements that are sent to SQL Server and the SQL Server result sets from these statements. Since BizTalk Server is tightly integrated with SQL Server, the analysis of a SQL Server Profile trace can be a useful tool for analyzing problems that may occur in BizTalk Server when reading from and writing to SQL Server databases. For information about how to use SQL Server Profiler, see "Using SQL Server Profiler" in SQL Server Books Online at http://go.microsoft.com/fwlink/?linkid=104423.
·         SQL Server Management Studio can be used to execute SQL statements directly against SQL Server databases. This functionality may be useful for querying the BizTalk Server databases or for updating the BizTalk Server databases in certain scenarios. For more information about using SQL Server Management Studio to execute SQL statements, see "Writing, Analyzing, and Editing Scripts with SQL Server Management Studio" in SQL Server Books Online at http://go.microsoft.com/fwlink/?linkid=104425.
·         For more information about resolving performance problem related to the BizTalk Server databases, see "Troubleshooting SQL Server" in BizTalk Server Help at http://go.microsoft.com/fwlink/?LinkId=154250.

woensdag 9 mei 2012

SAP calling RFC hosted in BizTalk

 I've configured a SAP receive port in BizTalk. However when trying to enable the receive location I got some errors in the error log saying ' 'saprfc.ini' failed: 'No such file or directory' '.  Here is the full error message:

The Messaging Engine failed to add a receive location "RECEIVE MIXED ERIKS SAP" with URL "sap://CLIENT=900;LANG=EN;@a/SAPSERVER/00?GWSERV=sapgw00&ListenerDest=TRADCOMSAPDEST&ListenerGwServ=sapgw00&ListenerGwHost=194.178.122.5&ListenerProgramId=TRADCOMSAPPROG&RfcSdkTrace=False&AbapDebug=False" to the adapter "WCF-SAP". Reason: "Microsoft.Adapters.SAP.RFCException: Details: ErrorCode=RFC_OK. ErrorGroup=RFC_ERROR_SYSTEM_FAILURE. SapErrorMessage=Open file 'saprfc.ini' failed: 'No such file or directory'.  AdapterErrorMessage=Error accepting incoming connection. RfcAccept returned RFC_HANDLE_NULL..

Apparently this file is used in the RFC library of SAP:
“The RFC library will read the saprfc.ini file to find out the connection type and all RFC-specific parameters needed to connect to an SAP system, or to register an RFC server program at an SAP gateway and wait for RFC calls from any SAP system.”

How to solve this issue?

First of all you'll need to create a System Variable called RFC_INI. To manage the Environment Variables you'll need to open the system properties and select 'Environment Variables...', as shown below.


Then create the new system variable RFC_INI with a filepath as value, for example C:\SAPINI\saprfc.ini.
 

Next we need to add the contents to our saprfc.ini file.  The values that I needed to provide include: 

FieldValuedescription
DEST TRADCOMSAPDEST In this case, this is the name of the RFC Destination that our BASIS team created for us from SM59.  More details here.
TYPE R Type R is for RFC server programs or for a client program working with another external program as RFC server program which is already registered at an SAP gateway.
GWHOST SAP_HOST_NAME In my case, this is the name of the physical server that his hosting the SAP Gateway.
GWSERVER SAP_GATEWAY_NAME The name of the SAP Gateway.  A standard naming convention is: SAPGW## where ## is the system number for the SAP instance that you are working on.
PROGID TRADCOMSAPPROG This is the name of the Program ID that has also been provided by BASIS. 



When you compare the data between the Receive Location and the saprfc.ini file, you'll see a certain symmetry between the two.  However, the values in the ini file take precedence.<br />

 
You'll need a restart of the BizTalk host instance, the one defined on the SAP adapter, for the changes to take effect.
This should be all to resolve the issue.

Source: Kent Weare's BizTalk Blog: SAP calling RFC hosted in BizTalk

woensdag 25 april 2012

Calling Pipelines with custom property settings from an orchestration

In my previous blog post I explained how to execute pipelines from an orchestration using the default pipeline property settings.
Now I would like to show you how to call pipelines from an orchestration while configuring the pipeline with custom property settings. To achieve this the standard methods wouldn't suffice.

First of all you'll need to add some extra functionalities. Here's my code to achieve this:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Data.SqlClient;
using System.Runtime.Serialization;

using Microsoft.XLANGs.Pipeline;
using Microsoft.BizTalk.PipelineOM;
using Microsoft.XLANGs.BaseTypes;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Data;
using System.Text.RegularExpressions;
using Microsoft.XLANGs.RuntimeTypes;
using Microsoft.XLANGs.Core;
using MIME;
using System.Net;

namespace TP.BTS.GlobalFunctions
{

public class PipelineInstance
    {
        internal Microsoft.BizTalk.PipelineOM.Pipeline pipeline = null;

        public static PipelineInstance CreateInstance(Type type)
        {
            PipelineInstance instance = new PipelineInstance();
            instance.pipeline = (Pipeline)Activator.CreateInstance(type);
            return instance;
        }

        public void ApplyInstanceConfig(String config)
        {
            try
            {
                using (Stream stream = new MemoryStream(Encoding.Unicode.GetBytes(config)))
                    LoadPerInstanceConfig(pipeline, stream);
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(String.Format("{0}", e));
                throw;
            }
        }

        #region Implementation

        private static void LoadPerInstanceConfig(Pipeline pipeline, Stream stream)
        {
            try
            {
                MethodInfo method =
                    typeof(Pipeline).GetMethod(
                        "LoadPerInstanceConfig"
                        , BindingFlags.NonPublic | BindingFlags.Instance);
                method.Invoke(pipeline, new object[] { stream });
            }
            catch (System.Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e);
                throw;
            }
        }

        #endregion
    }

    public static class PipelineManager
    {
        #region receive pipeline
        public static ReceivePipelineOutputMessages ExecuteReceivePipeline(Type type, XLANGMessage message)
        {
            string EmptyConfig =
                        @"<Root
                        xmlns:xsd='http://www.w3.org/2001/XMLSchema'
                        xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
                        <Stages />
                    </Root>";

            return ExecuteReceivePipeline(type, EmptyConfig, message);
        }

        public static ReceivePipelineOutputMessages ExecuteReceivePipeline(Type type, String config, XLANGMessage message)
        {
            try
            {
                PipelineInstance pipeline = PipelineInstance.CreateInstance(type);
                pipeline.ApplyInstanceConfig(config);
                return ExecuteReceivePipeline(pipeline, message);
            }
            catch (TargetInvocationException e)
            {
                System.Diagnostics.Debug.WriteLine(e);
                ThrowPipelineException(e);
                throw;
            }
            catch (XLANGPipelineManagerException e)
            {
                throw;
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.Assert(false, String.Format("Unexpected exception: {0}", e));
                System.Diagnostics.Debug.WriteLine(e);
                throw;
            }
        }

        public static ReceivePipelineOutputMessages ExecuteReceivePipeline(PipelineInstance pipeline, XLANGMessage message)
        {
            Microsoft.BizTalk.PipelineOM.Pipeline pipelineOM = pipeline.pipeline;

            try
            {
                MethodInfo method =
                    typeof(XLANGPipelineManager).GetMethod(
                        "ExecutePipeline"
                        , BindingFlags.NonPublic | BindingFlags.Static
                        , null, new Type[] { typeof(ReceivePipeline), typeof(XLANGMessage) }
                        , null);
                return (ReceivePipelineOutputMessages)method.Invoke(null, new object[] { pipelineOM, message });
            }
            catch (TargetInvocationException e)
            {
                System.Diagnostics.Debug.WriteLine(e);
                ThrowPipelineException(e);
                throw;
            }
        }
        #endregion

        #region send pipeline
        public static void ExecuteSendPipeline(Type type, SendPipelineInputMessages pipelineinputmsg, XLANGMessage message)
        {
            string EmptyConfig =
                        @"<Root
                        xmlns:xsd='http://www.w3.org/2001/XMLSchema'
                        xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
                        <Stages />
                    </Root>";

            ExecuteSendPipeline(type, EmptyConfig, pipelineinputmsg, message);
        }

        public static void ExecuteSendPipeline(Type type, String config, SendPipelineInputMessages pipelineinputmsg, XLANGMessage message)
        {
            try
            {
                PipelineInstance pipeline = PipelineInstance.CreateInstance(type);
                pipeline.ApplyInstanceConfig(config);
                ExecuteSendPipeline(pipeline, pipelineinputmsg, message);
            }
            catch (TargetInvocationException e)
            {
                System.Diagnostics.Debug.WriteLine(e);
                ThrowPipelineException(e);
                throw;
            }
            catch (XLANGPipelineManagerException e)
            {
                throw;
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.Assert(false, String.Format("Unexpected exception: {0}", e));
                System.Diagnostics.Debug.WriteLine(e);
                throw;
            }
        }

        public static void ExecuteSendPipeline(PipelineInstance pipeline, SendPipelineInputMessages pipelineinputmsg, XLANGMessage message)
        {
            Microsoft.BizTalk.PipelineOM.Pipeline pipelineOM = pipeline.pipeline;

            try
            {
                MethodInfo method =
                    typeof(XLANGPipelineManager).GetMethod(
                        "ExecutePipeline"
                        , BindingFlags.NonPublic | BindingFlags.Static
                        , null, new Type[] { typeof(SendPipeline), typeof(SendPipelineInputMessages), typeof(XLANGMessage) }
                        , null);
                method.Invoke(null, new object[] { pipelineOM, pipelineinputmsg, message });
            }
            catch (TargetInvocationException e)
            {
                System.Diagnostics.Debug.WriteLine(e);
                ThrowPipelineException(e);
                throw;
            }
        }
       
        #endregion

        #region Implementation

        private static void ThrowPipelineException(Exception innerException)
        {
            ConstructorInfo constructor =
                typeof(XLANGPipelineManagerException).GetConstructor(
                    BindingFlags.NonPublic | BindingFlags.Instance
                    , null
                    , new Type[] { typeof(String), typeof(Exception) }
                    , null);
            throw (XLANGPipelineManagerException)constructor.Invoke(
                    new object[] {
                    innerException != null ? 
                    innerException.InnerException.Message != null? 
                    innerException.InnerException.Message : innerException.Message: 
                    String.Empty, innerException });
        }

        #endregion
    }
    }

Now, here's how to execute a receive pipeline using the custom property settings.
First create a variable of type TP.BTS.GlobalFunctions.PipelineInstance (called ReceivePipeline in my example). Also create a variable PipelineOutputMsg of type Microsoft.XLANGs.Pipeline.ReceivePipelineOutputMessages.
This would be the code to execute the pipeline then:
ReceivePipeline = 
TP.BTS.GlobalFunctions.PipelineInstance.CreateInstance(typeof(TC_FFRECEIVE.TC_FFRECEIVE));

ReceivePipeline.ApplyInstanceConfig(
@"<Root xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
  <Stages>
    <Stage CategoryId='9d0e4103-4cce-4536-83fa-4a5040674ad6'>
      <Components>
        <Component Name='TP.BTS.PIPELINES.CustomXMLRECEIVECOMPONENT'>
          <Properties />
        </Component>
      </Components>
    </Stage>
    <Stage CategoryId='9d0e4105-4cce-4536-83fa-4a5040674ad6'>
      <Components>
        <Component Name='Microsoft.BizTalk.Component.FFDasmComp'>
          <Properties>
            <DocumentSpecName vt='8'>FLATFILE.ORDERS.FF_ORDERS,FLATFILE.ORDERS, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a8e07cee919011d4</DocumentSpecName>
          </Properties>
        </Component>
      </Components>
    </Stage>
  </Stages>
</Root>");



PipelineOutputMsg = TP.BTS.GlobalFunctions.PipelineManager.ExecuteReceivePipeline(ReceivePipeline,MsgICMTxt);
The XML assigned when calling the ApplyInstanceConfig is the same as you can find when exporting the binding file with the Biztalk Admin Console.
It is that simple :).

Calling a send pipeline with custom property settings would be done like this:
Create a variable SendPipelineInput from type Microsoft.XLANGs.Pipeline.SendPipelineInputMessages. I've also used a variable PipelineConfig of type System.String.
Here's the code I've used:
SendPipelineInput.Add(MsgINVOIC_EDI);

PipelineConfig = @"<Root xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
  <Stages>
    <Stage CategoryId='9d0e4101-4cce-4536-83fa-4a5040674ad6'>
      <Components>
        <Component Name='TP.BTS.PIPELINES.CUSTOMSENDEDIPARTYRESOLUTION.CUSTOMSENDEDIPARTYRESOLUTION'>
          <Properties>
            <OverrideRcvprn vt='8'>" + MsgINVOIC_GEN(ORDERS.ORDERSPropertySchema.RCVPRN) + @"</OverrideRcvprn>
            <OverrideRecipient vt='11'>-1</OverrideRecipient>
            <OverrideSndprn vt='8'>" + MsgINVOIC_GEN(ORDERS.ORDERSPropertySchema.SNDPRN) + @"</OverrideSndprn>
          </Properties>
        </Component>
      </Components>
    </Stage>
    <Stage CategoryId='9d0e4107-4cce-4536-83fa-4a5040674ad6'>
      <Components>
        <Component Name='Microsoft.BizTalk.Edi.Pipelines.EdiAssembler'>
          <Properties />
        </Component>
      </Components>
    </Stage>
    <Stage CategoryId='9d0e4108-4cce-4536-83fa-4a5040674ad6'>
      <Components>
        <Component Name='TP.BTS.PIPELINES.CustomXMLSENDCOMPONENT'>
          <Properties />
        </Component>
      </Components>
    </Stage>
  </Stages>
</Root>";

OrdersOutputInterchange = null;

TP.BTS.GlobalFunctions.PipelineManager.ExecuteSendPipeline(typeof
(CUSTOM_EDI_SEND.CUSTOM_EDI_SEND), PipelineConfig, SendPipelineInput,OrdersOutputInterchange);
And that should do the trick.

Hope you enjoyed this post.

vrijdag 20 april 2012

Call pipelines from an orchestration

Calling a pipeline from an orchestration is quite easy.

First of all you need to add a reference to the Microsoft.XLANGs.Pipeline.dll and Microsoft.BizTalk.Pipeline.dll assemblies. When this is done you'll be able to execute a receive pipeline as follows:
ReceivePipelineOutput = Microsoft.XLANGs.Pipeline.XLANGPipelineManager.ExecuteReceivePipeline
(typeof(ShemasAndPipelines.ReceiveCustOrdres), OrdersInputInterchange);
To get all messages coming out the pipeline, you'll have to loop over the batch and get all messages like this:
 ReceivePipelineOutput.GetCurrent(OrdersInputMsg);
For the execution of a send pipeline you'll need to create a variable of type Microsoft.XLANGs.Pipeline.SendPipelineInputMessages. then call the method add on this variable which adds message of type Microsoft.XLANGs.BaseType.XLANGMessage.
SendPipelineInputMessages.Add(OrderSummary);
To execute the send pipeline, you'll have call the ExecuteSendPipeline method with the just created SendPipelineInputMessages and the output message as follows:
Microsoft.XLANGs.Pipeline.XLANGPipelineManager.ExecuteSendPipeline(typeof
(ShemasAndPipelines.SendCustOrdersPipeline), SendPipelineInput, OrdersOutputInterchange);
This way of executing pipelines will execute the pipelines using the default settings for all pipeline properties. How to execute pipelines from an orchestration with custom settings for the pipeline properties will be explained in my next blogs.

a more detailed explanation can be found here