LoadGen Reloaded

The BizTalk load generation utility, originally released by Microsoft several months ago, was quickly removed from their downloads page for enhancement. The enhanced version is now available for download here.
This tool can work in tandem with the BizTalk Performance Tester to simulate real-world load in your testing enviroment and test your BizTalk solution performance.

List of various BAM Questions

You can also access this from my original blog,

http://vamsibiztalk.blogspot.com/2006/01/list-of-various-bam-questions.html

I have created the list of problems or questions we might encounter with BAM, some of them are my own experiences and some I have gathered from different sources and bundled up in one forum,

This article explains some of the questions posted on the BAM, thought would be useful for everyone whose working on BAM, any comments are welcome:

SharePoint Services Errors for BizTalk

Error 1:




While configuring the databases used by Windows SharePoint Services
, might receive the following error,
Line 1: Incorrect syntax near ‘COLLATE’. (Error code: 170).



Solution: Provide the SQL Server Access rights to the BTSService, to do this go to security, logins and add the BTSService (User) which is member of administrator, and add to the all the server roles.




Error 2:



templatepick.aspx – page not found



When you create a new top level site under a parent site in sharepoint, it brings up the page saying it has been created successfully, when we click on the sites URL to specifiy the template it should display the default template selection wizard, but instead we might receive a page not found error.



Solution: If you want to delete the following sub site under sites, click on Documents and Lists, under Sites, delete the above site and recreate it, still problem occurs delete the root sites and recreate.

Error 3:



The “WSSLib” adapter is suspending an outbound message going to destination URL:”http://localhost/sites/SomeException/Exceptions”. Details:”The request failed with HTTP status 404: Not Found.”.



Solution: This means that you haven’t put the WSSWebServices.dll in to the C:\Program Files\Common Files\Microsoft Shared\web server extensions\60\ISAPI\BIN folder and WSSDocLibService.asmx in to the C:\Program Files\Common Files\Microsoft Shared\web server extensions\60\ISAPI folder, hence it was not able to find these files, so the following exception occurred.



Note: Kindly check your internal path using the IIS manager,WebSites/_vti_bin, right click and view the properties, capture the local path located under virtual directory tab you should be able to find the folder path location.




Error 4:



When ever we click on ‘Upgrade a server or virtual server’ in SharePoint site, we might get the annoying help file,



“To upgrade your server to Microsoft Windows SharePoint Services, run Setupsts.exe. Running Setupsts.exe upgrades your server and the default virtual server. If you have additional virtual servers to upgrade, you can upgrade each virtual server individually by using the upgrade operation with the Stsadm.exe command-line tool.”



Solution: Prohibit the FrontPage from the IIS and remove it from add/remove program, then reset the IIS.
Try to open the site again and this time, You should see the following response, Virtual Server Successfully Extended, This would allow us to browse to the next level in the sites,
You can open the home page for your new Web site in your browser by using a link on the confirmation page. You can continue to extend other virtual servers or configure Self-Service Site Creation so users can create their own sites.



Error 5:



“1057 while trying to query service SPTimer.”



Solution:



Make sure you enter the user name as “domain\user name” or “machine name\user name;” otherwise, you get the following error: “System Error 1057 while trying to query service SPTimer,



Installing SharePoint:

Solution:
To Install Install Windows SharePoint Services without installing MSDE,
basically need to do the following,
C:\Program Files\STS2Setup_1033>setupsts.exe remotesql=yes



for more info, Kindly go to the following sites



http://weblogs.asp.net/jan/archive/2004/02/03/66544.aspx


http://www.microsoft.com/resources/documentation/wss/2/all/adminguide/en-us/stsc01.mspx


http://www.codeguru.com/Csharp/.NET/net_asp/miscellaneous/article.php/c8569/

 

Mapping complex conditions in BizTalk with XSLT

Recently I found myself in a situation where I needed to evaluate a set of complex conditions that I could not use the Business Rules Engine for. The BizTalk mapper was able to achieve the conditionality by chaining a series of about 21 functoids together but this became very unmanageable especially since I was combining false statements to see if both were false, then returning a true to an “And” functoid (&) which evaluated another branch as true and passed a result to the node in the destination schema, you get the idea.

An easier way is to plug in XSLT. There are disadvantages to doing this, the main one being its maintainability and transparency but when faced with the daunting set of functoids described above, it looked a decent option.

The XSLT function that I used was the <xsl:choose> statement, inside the statement was a set of conditions which, if true, would return a value/values to the destination schema. In the last part of the statement was the <xsl:otherwise> condition which could set values if the conditions presented were not valid and you had a default you wanted to present in that event.

<xsl:variable name=”var:vAnnuity” select=”count(/*[local-name()=’InternalSupport’ and namespace-uri()=’http://internal_support’]/*[local-name()=’LoanPartItems’ and namespace-uri()=” and Method=’Annuity’])” />

<xsl:variable name=”var:vLinear” select=”count(/*[local-name()=’InternalSupport’ and namespace-uri()=’http://internal_support’]/*[local-name()=’LoanPartItems’ and namespace-uri()=” and Method=’Linear’])” />

<xsl:variable name=”var:vTotalCount” select=”count(/*[local-name()=’InternalSupport’ and namespace-uri()=’http://internal_support’]/*[local-name()=’PartItems’ and namespace-uri()=”])” />

<xsl:variable name=”var:vHasValidEndowment” select=”count(/*[local-name()=’InternalSupport’ and namespace-uri()=’http://internal_support’]/*[local-name()=’LoanPartItems’ and namespace-uri()=” and isValid =’true’])” />

<xsl:variable name=”var:vHasValidId” select=”count(/*[local-name()=’InternalSupport’ and namespace-uri()=’http://internal_support’]/*[local-name()=’Ready’ and HasValidId =’true’])” />

<xsl:element name=”LeningSoort”>

    <xsl:choose>

        <xsl:when test=”$var:vAnnuity = $var:vTotalCount”>

            <xsl:value-of select=”1″ />

        </xsl:when>

        <xsl:when test=”$var:vLinear = $var:vTotalCount”>

            <xsl:value-of select=”2″ />

        </xsl:when>

        <xsl:when test=”($var:vHasValidEndowment = $var:vTotalCount) and ($var:vHasValidId = $var:vTotalCount)”>

            <xsl:value-of select=”3″ />

        </xsl:when>

        <xsl:otherwise>

            <xsl:value-of select=”4″ />

        </xsl:otherwise>

    </xsl:choose>

</xsl:element>

Of course each specific case requires different XSLT, but this should provide a framework of how to do this within a functoid.

To set up the XSLT:

Create XSLT similar to the one above which meets your needs
Drop a scripting functoid on your map
Connect the output parameter to the node you want to create
Note: do no include any input parameters, the XSLT is setup already to look them up
Open the scripting functoid’s, click the () inside “Configure Functoid Script”
Under “Script type” choose “Inline XSLT”
Paste your XSLT snippet in the text box

BizTalk 2006 and the Sql Server 2005 Service Broker Adapter (Beta 2)

Jesús Rodríguez has finished a Beta 2 version of  Service Broker Enhancements Adapter for BizTalk Server 2006. They are looking for beta testers, so please go HERE if interested. Service Broker is an exciting new feature for Microsoft SQL Server 2005. Now you can integrate BizTalk Messaging with Service Broker Messaging, using this important new adapter.


 

BizTalk 2006 – MOM 2005 Throttling Scripts

At my current client we have implemented various operational tools to manage suspended queues, cleaning up dead messages, monitoring states and throttling. We had created a lot of these utilities to achieve functionality that could either not be produced easily through the standard BizTalk 2004 interface, the functionality provided was not enough to meet our requirements or there was some necessity to implement some automation.


A lot of these operational utilities were developed as either services or scheduled tasks using an appropriate scheduling mechanism such as SQL Jobs or Windows Scheduled Tasks. Some investigation had taken place into MOM, but at the time the 2000 version that was reviewed was not going to be deployed within the company.


During our current development using BizTalk 2006 we have had the opportunity to investigate the use of MOM 2005 as part of the overall solution. This has obviously lead to some initial review of whether it can be used to provide the operational utilities that were previously developed in a more accessible manner, along with any improvements in development time.


This leads me on to the purpose of this blog posting. One of the operational utilities that is offered as part of the service I am implementing on BizTalk 2006 is the ability to throttle Receive Locations. There is a requirement stating that if a publisher is submitting messages at such a rate whereby the BizTalk Group cannot handle the load, then an automated mechanism of disabling and enabling the Receive Location should exist.


For example, you have determined that the hardware and configuration of your BizTalk Group can handle scenarios where the host queue associated to that Receive Location is backing up to approximately 100 instances. You may want to throttle the Receive Location when the queue gets above this threshold so that the whole BizTalk Group does not sustain sufficient strain to cause itself problems.


At this point it may be worthwhile noting that you can actually throttle BizTalk at various levels from within the BizTalk Administration Console as shown in the figures below



Figure 1 – Host Throttling Properties



Figure 2 – Throttling Thresholds


The standard throttling may be more applicable to your own requirements – although it does not provide quite the flexibility of your own implementation – and in any event would also be the fall back mechanism for the solution discussed in this post. Also, please note that any figures discussed here are purely for demonstration purposes only, they are not realistic.


Anyway, with BizTalk 2006 you now have a number of extra performance counters that can be extremely useful. One of these is the Host Queue Length as shown below



Figure 3 – Host Queue Length Performance Counter


Before this was exposed in BizTalk 2006 you probably wrote stored procedures that returned you the queue lengths that you were interested and called these from your operational utilities. Fortunately you do not need to be concerned with this anymore and as they are exposed as performance counters we can employ them within a MOM 2005 utility.


As discussed above, we wish to throttle a specific Receive Location when it hits a certain threshold. What does this entail? Well, standard throttling means that when an observed figure goes above the threshold for a specific item then the item is disabled until a time at which the observed figure goes below another threshold. These are referred to as High and Low Watermarks.


So what we need to do is identify when the Host Queue counter shown above gets above the High Watermark and disabled a specified Receive Location. Then, once BizTalk has managed to process some of the backlog and the Host Queue counter resumes to a level below a Low Watermark then re-enable the Receive Location. This will be achieved using Performance Rules in MOM 2005 that fire Response scripts when the watermarks are met.


Firstly, we create a Rule Group in MOM 2005 that will group these rules (and any other you may deem appropriate) together. Within the MOM 2005 Administrator Console, we navigate to the Management Packs %uf0e0 Rule Groups node, right-click and select Create Rule Group. You will then be presented with a screen similar to that shown below. Just enter some appropriate information.



Figure 4 – New Rule Group Properties


A generic Knowledge Base screen will appear that allows you to enter useful related information as part of your company’s Knowledge Base, just skip that screen for the moment by clicking Finish. You will then be prompted whether you wish to deploy to a group of computers.



Figure 5 – Rule Deployment Prompt


You then need to select the Computer Group that you wish to deploy to if you have one set-up or do this at a later date. For further information on Computer Groups, please refer to your MOM 2005 documentation. You should now have a newly created Rule Group as shown in the following figure



Figure 6 – MOM 2005 Administrator


We are creating Performance Rules, so navigate to the Performance Rules node within the newly created Rule Group, right-click and select Create Performance Rule. You will then be prompted to select a type of Performance Rule. As we wish to execute scripts based upon a threshold being met, select the Compare Performance Data (Threshold) option.


The next screen is trying to obtain what Provider to use. We need a new Windows NT Performance Counter Provider for the Host Queue counter we identified earlier. Click on the New button to create this provider and then use the dialog box that opens to choose this performance counter. At this point you need to browse to the Computer that contains the BizTalk 2006 installation and select the Host Queue performance counter much in the same manner as if you were using Performance Monitor, as shown in the figure below.



Figure 7 – Windows Performance Counter Provider Properties


Notice that we simply use the <All> hosts selection, which will return the queue depth for all the hosts in the BizTalk Group. We also use a sample rate of every 5 seconds and simply stick with the default naming. As mentioned previously, these figures and selections are simply used for demonstration purposes and can be altered to your requirements.


Now we have set-up this Windows Performance Counter Provider we want to set the threshold at which our script will execute. Back on the original dialog box we simply scroll through all the selections leaving them default until the Threshold Rule Properties – Threshold dialog. At this point we are defining the Performance Rule to use for disabling a Receive Location, so we will enter a High Watermark value in this dialog box. This is shown below:



Figure 8 – Threshold Rule Properties


Notice that we are using the “greater than the following value” option and specifying 100. This will mean that the script we wish to fire will do so once the Host Queue value exceeds 100.


The next screen in the wizard allows you to define an alert to raise when this criteria has been met. Once again, this all depends on your own particular requirements, but I would have this on at the very least during development and testing, as it assists in debugging any issues you may experience.



Figure 9 – Threshold Alert Properties


Scroll through the Alert Supression screen leaving the default alert suppression so that you do not receive unnecessary alerts and then you arrive at the Responses dialog box. This is where you define the response to this Performance Rule being met and where we wish to execute our script to disable the Receive Location.


Choose Add %uf0e0 Launch a Script and you will be prompted with the Launch a Script dialog box. You may select an existing script you have created from here or define a new one. We will be entering a new one for this demonstration, so click the New button. You will be asked to enter a name and description for the script and then select the Language that the script is written in.



Figure 10 – General Script Properties


Enter some appropriate information, make sure the VBScript language is selected and click Next. You will then be shown an area where you may enter your script.


Now, I have been quite impressed with MOM 2005, but this is one of the areas that certainly need improvement. Not only does this dialog box not resize, but there are none of the User Interface improvements that you are used to in products such as Visual Studio. So you are left working with a bog standard text box. Not the most exhilarating experience that’s for sure. I tend to write the script elsewhere and debug as much as possible using cscript and then port it for MOM 2005 and paste into this teeny box.


The script you need to paste here is shown below. Note that this is still a Proof of Concept at this stage and I do need expect to be held liable if it affects your system in any way! By the time you have read this it may have changed already (a prime example is to add multiple Receive Locations), so simply use it as a basis for understanding the conceptual points I am trying to discuss.


‘————————————————————————–

‘ WMI script to disable the specified Receive Location. The Receive Location
‘ to disable is specified by name as an argument passed to the script.

‘————————————————————————–
‘ History:

‘ (03-Jan-2006 Matt Hall) – Created

‘————————————————————————–


‘ Explicit declaration of variables
Option Explicit


‘ Event Constant definitions
Const EVENT_TYPE_SUCCESS = 0
Const EVENT_TYPE_ERROR = 1
Const EVENT_TYPE_WARNING = 2
Const EVENT_TYPE_INFORMATION = 4
Const EVENT_TYPE_AUDITSUCCESS = 8
Const EVENT_TYPE_AUDITFAILURE = 16


‘ VarSet Constants
Const RECEIVE_LOCATION_CHECKER_NAME = “Receive Loc Checker”
Const RECEIVE_LOCATION_CHECKER_STATE = “Receive Loc Checker State”


‘ Receive Location Checker States
Const RECEIVE_LOCATION_ENABLED = 1
Const RECEIVE_LOCATION_DISABLED = 0


‘ Retrieve the DebugMode parameter to determine whether we want to be in debug mode
Dim blnDebugMode : blnDebugMode = CBool(GetParam(“DebugMode”))


‘ Start processing
If GetReceiveLocationState = RECEIVE_LOCATION_ENABLED Then
 If blnDebugMode = true Then
  CreateDebugEvent(“GetReceiveLocationState returned true”)
 End If
 Call DisableReceiveLocation()
 SetReceiveLocationState(RECEIVE_LOCATION_DISABLED)
 
Else
 If blnDebugMode = true Then
  CreateDebugEvent(“GetReceiveLocationState returned false”)
 End If
End If


‘————————————————————————–

‘ Subroutine that disables the specified Receive Location

‘————————————————————————–
Sub DisableReceiveLocation()


 ‘ If we are in debug mode then create an event to indicate we have entered the DisableReceiveLocation sub routine
 If blnDebugMode = true Then
  CreateDebugEvent(“DisableReceiveLocation Start”)
 End If


 ‘ Get the Receive Location name that was passed
 Dim strReceiveLocationName : strReceiveLocationName = GetParam(“RecLoc”)


 ‘ Build a query to retrieve the WMI object containing this Receive Location
 Dim strQuery : strQuery = “SELECT * FROM MSBTS_ReceiveLocation WHERE Name =””” & strReceiveLocationName & “”””
 Dim objRecLocs : Set objRecLocs = GetObject(“Winmgmts:!root\MicrosoftBizTalkServer”).ExecQuery(strQuery)


 ‘ If we are in debug mode then create an event to display the receive location information
 If blnDebugMode = true Then
  CreateDebugEvent(“strReceiveLocationName = ” & strReceiveLocationName & “, strQuery = ” & strQuery & “, objRecLocs.Count = ” & cStr(objRecLocs.Count))
 End If


 ‘ If a Receive Location was found matching the specified name then disable it
 If objRecLocs.Count > 0 then
  Dim objRecLoc
  For Each objRecLoc in objRecLocs
   objRecLoc.Disable
  Next
 ‘ Otherwise a Receive Location was not found matching that name, so output this to the ScriptContext
 Else
  CreateEvent 100, EVENT_TYPE_INFORMATION, “DisableReceiveLocationScript”, “A Receive Location was not found matching the name equal to ” & strReceiveLocationName
 End If


 Set objRecLocs = Nothing
   
End Sub


‘————————————————————————–

‘ Function that returns the specified parameter value from the ScriptContext

‘————————————————————————–
Function GetParam(strParamName)
 Dim objParameters : Set objParameters = ScriptContext.Parameters
 Dim vntVariable : vntVariable = objParameters.get(strParamName)


 Set objParameters = Nothing


 GetParam = vntVariable
End Function



‘————————————————————————–

‘ Subroutine that submits an event to the ScriptContext

‘————————————————————————–
Sub CreateEvent(intEventNumber, intEventType, strEventSource, strEventMessage)
 Dim objEvent : Set objEvent = ScriptContext.CreateEvent()
 objEvent.EventSource = strEventSource
 objEvent.EventNumber = intEventNumber
 objEvent.EventType = intEventType
 objEvent.Message = strEventMessage
 ScriptContext.Submit objEvent
 Set objEvent = Nothing


End Sub


‘————————————————————————–

‘ Subroutine that takes a string and submits an appropriate event to the
‘ ScriptContext for debugging output

‘————————————————————————–
Sub CreateDebugEvent(strDebugOutput)
 ‘ Note that we prefix the message even though this appears in the Source of the event as it makes it easier to
 ‘ read when viewing the log
 CreateEvent 100, EVENT_TYPE_INFORMATION, “DisableReceiveLocationScript Debug”, “DisableReceiveLocationScript: ” & strDebugOutput
End Sub


‘————————————————————————–

‘ Function that returns the state of the Receive Location we are checking

‘————————————————————————–
Function GetReceiveLocationState()


 ‘ Debug output showing function has started
 If blnDebugMode = true Then
  CreateDebugEvent(“GetReceiveLocationState Started”)
 End If


 ‘ Return the string to use for the name of the VarSet
 Dim strReceiveLocCheckName : strReceiveLocCheckName = ReceiveLocationCheckerNameByMachine


 ‘ Debug output showing the VarSet name we will be using
 If blnDebugMode = true Then
  CreateDebugEvent(“strReceiveLocCheckName = ” & strReceiveLocCheckName)
 End If


 ‘ Obtain the ScriptState
 Dim objScriptState : Set objScriptState = ScriptContext.GetScriptState()
 
 ‘ Obtain the VarSet containing the state value we require
 Dim objRecLocCheckerVarSet : Set objRecLocCheckerVarSet = objScriptState.GetSet(strReceiveLocCheckName)


 ‘ Obtain the state value
 Dim vntRecLocCheckerState : vntRecLocCheckerState = objRecLocCheckerVarSet.get(RECEIVE_LOCATION_CHECKER_STATE)
 
 ‘ Debug output showing the state value
 If blnDebugMode = true Then
  CreateDebugEvent(“vntRecLocCheckerState returned ” & CStr(vntRecLocCheckerState))
 End If
 
 ‘ Release resources
 Set objScriptState = Nothing
 Set objRecLocCheckerVarSet = Nothing


 ‘ Return state value
 GetReceiveLocationState = vntRecLocCheckerState
End Function



‘————————————————————————–

‘ Sub routine that sets the Receive Location state in the ScriptContext so
‘ we can query this value between both the disable and enable scripts. This
‘ allows us to determine the state of the Receive Location without having
‘ to undertake any unnecessary processing.

‘————————————————————————–
Sub SetReceiveLocationState(intReceiveLocationState)


 ‘ Debug output showing sub procedure has started
 If blnDebugMode = true Then
  CreateDebugEvent(“SetReceiveLocationState Started”)
 End If


 ‘ Return the string to use for the name of the VarSet
 Dim strReceiveLocCheckName : strReceiveLocCheckName = ReceiveLocationCheckerNameByMachine


 ‘ Debug output showing the VarSet name we will be using
 If blnDebugMode = true Then
  CreateDebugEvent(“strReceiveLocCheckName = ” & strReceiveLocCheckName)
 End If


 ‘ Obtain the ScriptState
 Dim objScriptState : Set objScriptState = ScriptContext.GetScriptState()


 ‘ Obtain the Receive Location Checker VarSet
 Dim objRecLocCheckerVarSet : Set objRecLocCheckerVarSet = objScriptState.GetSet(strReceiveLocCheckName)


 ‘ Save variable changes back to the VarSet
 Call objRecLocCheckerVarSet.put(RECEIVE_LOCATION_CHECKER_STATE, intReceiveLocationState)
 
 ‘ Save the VarSet
 Call objScriptState.SaveSet(strReceiveLocCheckName, objRecLocCheckerVarSet)
 
 ‘ Release resources
 Set objScriptState = Nothing
 Set objRecLocCheckerVarSet = Nothing
End Sub


‘————————————————————————–

‘ Function that returns the Receive Location Checker Name value to use for
‘ storing the VarSet. We add the Target Computer so we know which BizTalk
‘ Server in the Group we are executing the script against. We also use the
‘ Receive Location name that was passed as a parameter to this script so the
‘ script can be executed against multiple Receive Locations if required.

‘————————————————————————–
Function ReceiveLocationCheckerNameByMachine()
 ReceiveLocationCheckerNameByMachine = RECEIVE_LOCATION_CHECKER_NAME + “#” + ScriptContext.TargetComputer + “#” + GetParam(“RecLoc”)
End Function


This script accepts a couple of parameters. The first of which is defining which Receive Location we are to be disabling, which is the unique name of the Receive Location. The second is simply a Debug parameter that I use in order to be able to output debug information to the MOM Alerts. If the debug parameter is set to true then the alerts are shown, otherwise they are not.


From the Script Properties – Parameters screen, click the Add button to add these two parameters to the script.




Figure 10 – Script Parameters to Add


Note that the names of these parameters must match those shown above, as they are referenced in the script. The value you enter is simply the default value to use and can be overridden by any Rule Responses that employ the script.


Click the Finish button and continue through the Rule definition dialog boxes using the default options until you reach the end where you must give it a name and save.


The above process has given you a quick walkthrough of how to set-up a Performance Rule that executes a script based upon a defined BizTalk 2006 Host Queue threshold. You must now add another rule that re-enables the Receive Location at a specified Low Watermark in the same manner as that which you have just created, using the script below.


Once you have added this rule you may deploy the rules to the BizTalk server you wish to test this on and then conduct some testing. For my test I simply flooded as many messages as I could into a File Receive Location that simply routed the messages to a folder on the same server. The results are shown in the following figure


 


Figure 11 – Performance Monitor Results


The white line shows the Host Queue length and you can observe the throttling in action by the peaks and troughs displayed. Obviously you can configure this to be more effective for your requirements and you can change the rate at which the Enable Receive Location checks so there is less time between the bursts of activity. But this post has simply been used as an introduction of what can be achieved with BizTalk 2006 and MOM 2005. I hope you have found it useful.



‘————————————————————————–

‘ WMI script to enable the specified Receive Location. The Receive Location
‘ to enable is specified by name as an argument passed to the script.

‘————————————————————————–
‘ History:

‘ (03-Jan-2006 Matt Hall) – Created

‘————————————————————————–


‘ Explicit declaration of variables
Option Explicit


‘ Event Constant definitions
Const EVENT_TYPE_SUCCESS = 0
Const EVENT_TYPE_ERROR = 1
Const EVENT_TYPE_WARNING = 2
Const EVENT_TYPE_INFORMATION = 4
Const EVENT_TYPE_AUDITSUCCESS = 8
Const EVENT_TYPE_AUDITFAILURE = 16


‘ VarSet Constants
Const RECEIVE_LOCATION_CHECKER_NAME = “Receive Loc Checker”
Const RECEIVE_LOCATION_CHECKER_STATE = “Receive Loc Checker State”


‘ Receive Location Checker States
Const RECEIVE_LOCATION_ENABLED = 1
Const RECEIVE_LOCATION_DISABLED = 0


‘ Retrieve the DebugMode parameter to determine whether we want to be in debug mode
Dim blnDebugMode : blnDebugMode = CBool(GetParam(“DebugMode”))


‘ Start processing
If GetReceiveLocationState = RECEIVE_LOCATION_DISABLED Then
 If blnDebugMode = true Then
  CreateDebugEvent(“GetReceiveLocationState returned true”)
 End If
 Call EnableReceiveLocation()
 SetReceiveLocationState(RECEIVE_LOCATION_ENABLED)
 
Else
 If blnDebugMode = true Then
  CreateDebugEvent(“GetReceiveLocationState returned false”)
 End If
End If


‘————————————————————————–

‘ Subroutine that enables the specified Receive Location

‘————————————————————————–
Sub EnableReceiveLocation()


 ‘ If we are in debug mode then create an event to indicate we have entered the EnableReceiveLocation sub routine
 If blnDebugMode = true Then
  CreateDebugEvent(“EnableReceiveLocation Start”)
 End If


 ‘ Get the Receive Location name that was passed
 Dim strReceiveLocationName : strReceiveLocationName = GetParam(“RecLoc”)


 ‘ Build a query to retrieve the WMI object containing this Receive Location
 Dim strQuery : strQuery = “SELECT * FROM MSBTS_ReceiveLocation WHERE Name =””” & strReceiveLocationName & “”””
 Dim objRecLocs : Set objRecLocs = GetObject(“Winmgmts:!root\MicrosoftBizTalkServer”).ExecQuery(strQuery)


 ‘ If we are in debug mode then create an event to display the receive location information
 If blnDebugMode = true Then
  CreateDebugEvent(“strReceiveLocationName = ” & strReceiveLocationName & “, strQuery = ” & strQuery & “, objRecLocs.Count = ” & cStr(objRecLocs.Count))
 End If


 ‘ If a Receive Location was found matching the specified name then enable it
 If objRecLocs.Count > 0 then
  Dim objRecLoc
  For Each objRecLoc in objRecLocs
   objRecLoc.Enable
  Next
 ‘ Otherwise a Receive Location was not found matching that name, so output this to the ScriptContext
 Else
  CreateEvent 100, EVENT_TYPE_INFORMATION, “EnableReceiveLocationScript”, “A Receive Location was not found matching the name equal to ” & strReceiveLocationName
 End If


 Set objRecLocs = Nothing
   
End Sub


‘————————————————————————–

‘ Function that returns the specified parameter value from the ScriptContext

‘————————————————————————–
Function GetParam(strParamName)
 Dim objParameters : Set objParameters = ScriptContext.Parameters
 Dim vntVariable : vntVariable = objParameters.get(strParamName)


 Set objParameters = Nothing


 GetParam = vntVariable
End Function



‘————————————————————————–

‘ Subroutine that submits an event to the ScriptContext

‘————————————————————————–
Sub CreateEvent(intEventNumber, intEventType, strEventSource, strEventMessage)
 Dim objEvent : Set objEvent = ScriptContext.CreateEvent()
 objEvent.EventSource = strEventSource
 objEvent.EventNumber = intEventNumber
 objEvent.EventType = intEventType
 objEvent.Message = strEventMessage
 ScriptContext.Submit objEvent
 Set objEvent = Nothing


End Sub


‘————————————————————————–

‘ Subroutine that takes a string and submits an appropriate event to the
‘ ScriptContext for debugging output

‘————————————————————————–
Sub CreateDebugEvent(strDebugOutput)
 ‘ Note that we prefix the message even though this appears in the Source of the event as it makes it easier to
 ‘ read when viewing the log
 CreateEvent 100, EVENT_TYPE_INFORMATION, “EnableReceiveLocationScript Debug”, “EnableReceiveLocationScript: ” & strDebugOutput
End Sub


‘————————————————————————–

‘ Function that returns the state of the Receive Location we are checking

‘————————————————————————–
Function GetReceiveLocationState()


 ‘ Debug output showing function has started
 If blnDebugMode = true Then
  CreateDebugEvent(“GetReceiveLocationState Started”)
 End If


 ‘ Return the string to use for the name of the VarSet
 Dim strReceiveLocCheckName : strReceiveLocCheckName = ReceiveLocationCheckerNameByMachine


 ‘ Debug output showing the VarSet name we will be using
 If blnDebugMode = true Then
  CreateDebugEvent(“strReceiveLocCheckName = ” & strReceiveLocCheckName)
 End If


 ‘ Obtain the ScriptState
 Dim objScriptState : Set objScriptState = ScriptContext.GetScriptState()
 
 ‘ Obtain the VarSet containing the state value we require
 Dim objRecLocCheckerVarSet : Set objRecLocCheckerVarSet = objScriptState.GetSet(strReceiveLocCheckName)


 ‘ Obtain the state value
 Dim vntRecLocCheckerState : vntRecLocCheckerState = objRecLocCheckerVarSet.get(RECEIVE_LOCATION_CHECKER_STATE)
 
 ‘ Debug output showing the state value
 If blnDebugMode = true Then
  CreateDebugEvent(“vntRecLocCheckerState returned ” & CStr(vntRecLocCheckerState))
 End If
 
 ‘ Release resources
 Set objScriptState = Nothing
 Set objRecLocCheckerVarSet = Nothing


 ‘ Return state value
 GetReceiveLocationState = vntRecLocCheckerState
End Function



‘————————————————————————–

‘ Sub routine that sets the Receive Location state in the ScriptContext so
‘ we can query this value between both the disable and enable scripts. This
‘ allows us to determine the state of the Receive Location without having
‘ to undertake any unnecessary processing.

‘————————————————————————–
Sub SetReceiveLocationState(intReceiveLocationState)


 ‘ Debug output showing sub procedure has started
 If blnDebugMode = true Then
  CreateDebugEvent(“SetReceiveLocationState Started”)
 End If


 ‘ Return the string to use for the name of the VarSet
 Dim strReceiveLocCheckName : strReceiveLocCheckName = ReceiveLocationCheckerNameByMachine


 ‘ Debug output showing the VarSet name we will be using
 If blnDebugMode = true Then
  CreateDebugEvent(“strReceiveLocCheckName = ” & strReceiveLocCheckName)
 End If


 ‘ Obtain the ScriptState
 Dim objScriptState : Set objScriptState = ScriptContext.GetScriptState()


 ‘ Obtain the Receive Location Checker VarSet
 Dim objRecLocCheckerVarSet : Set objRecLocCheckerVarSet = objScriptState.GetSet(strReceiveLocCheckName)


 ‘ Save variable changes back to the VarSet
 Call objRecLocCheckerVarSet.put(RECEIVE_LOCATION_CHECKER_STATE, intReceiveLocationState)
 
 ‘ Save the VarSet
 Call objScriptState.SaveSet(strReceiveLocCheckName, objRecLocCheckerVarSet)
 
 ‘ Release resources
 Set objScriptState = Nothing
 Set objRecLocCheckerVarSet = Nothing
End Sub


‘————————————————————————–

‘ Function that returns the Receive Location Checker Name value to use for
‘ storing the VarSet. We add the Target Computer so we know which BizTalk
‘ Server in the Group we are executing the script against. We also use the
‘ Receive Location name that was passed as a parameter to this script so the
‘ script can be executed against multiple Receive Locations if required.

‘————————————————————————–
Function ReceiveLocationCheckerNameByMachine()
 ReceiveLocationCheckerNameByMachine = RECEIVE_LOCATION_CHECKER_NAME + “#” + ScriptContext.TargetComputer + “#” + GetParam(“RecLoc”)
End Function

BizTalk 2004 Naming Convention. Names of artifacts in Orchestrations


BizTalk 2004 Naming Conventions


“Scott Colestock” <scolestock@community.nospam> wrote in message news:eeY5KIjEGHA.984@tk2msftngp13.phx.gbl
> In general, try using more “Group” shapes to make orchestrations more
> self-documenting…
>
> A general text annotation feature in the designer would be great, wouldn’t
> it?


Of course I use it, but not on each shape!


You know, name of the most shapes can be based ONLY on the names of the schemas. Usualy all what we want to know in orchestrations it’s the “message flow” and “message transformation”. Think of that. 


Schemas give us the main information about the messages. Icon information is enough to understand what exactly happened in shape under the messages: send, receive, mapping, etc.
If I’m working with the Orch which was created by somebody else, the standard way to review this orch is:
* look for the message of the shape (click the shape and see the properties)
* look for the schema of these messages (click the message and see the properties)
We have to click, click, click… Why?

If creator of the Orch uses the proposed naming convention all these steps disappeared. We can see exactly the “schema flow” and “schema transformation”.



 


Goals:



l Readable names


l Unambiguous names


l Fast-created names (using Copy-Past)


l Fast search in the lists of BizTalk Explorer, Visual Studio and BizTalk Administration Manager


 


Chapter 1: Names of artifacts in Orchestrations


Problem with shape names in Orchestrations:


Shapes too small to display long names (12-18 chars).


Frankly it was the main goal this document to take into consideration this problem. If we use the “BizTalk 2004 Naming Conventions” by Scott Colestock


http://www.traceofthought.net/misc/BizTalk%20Naming%20Conventions.htm


the result is pity, we create too long names. L We have to “hover mouse over” shape or click shape to show Properties window to “understand” this shape. The names are complicated.




Useful features:



l Shape names are not the “real names”. In reality they are the descriptions (excluding the Port shapes names). It means we can give the same names to the different shapes without conflicts and we can use spaces inside the names.


l Icons of shapes give us the useful information. We have icons and don’t have to repeat the purpose the shapes by words. For example, if we change a name of Construction shape from “Construct Input message” to “Input message” we get more clear definition because we have the Construct icon + name. Unfortunately the meaning of the icons sometimes is not so clear. For example, the icons on the Send and Receive shapes look as mistaken: the arrow on Send shape icon points “inside” and the arrow on Receive shape points “outside”. But it’s the matter of habit. (This is another naming problem in BizTalk. See http://geekswithblogs.net/leonidganeline/archive/2006/12/18/101541.aspx)


l Shape names are not used in any list (exclude the Port shapes names). We don’t have to use any rules to make the “well-sorted” names (it’s the main purpose of the prefixes)



 


Generic rules:


%u00b7 Purpose the most of the shapes is processing the messages. We can unambiguous describe the messages by they type that’s mean by they schema. That is why in the most cases using the schema names as the message names gives us the main information about this message. That is why in the most cases using the schema names as the shape names give us the main information about this shape. Send shape with name “ASC_X12_311” means … exactly!


%u00b7 Names of objects start from Capital letter and other names start from the small letters.
For example: [Send]“Account”, [Create Account]”from Order”


%u00b7 Don’t repeat the meaning of shape icon by word.
For example:
not “construct Account”[name of Construct shape] + “transform Order to Account”[name of Transform shape inside this Construct shape]
but “Account” + “from Order”


%u00b7 Don’t repeat words from outside shape into the inside shape.
For example:
not “Account”[name of Construct shape] + “Order to Account”[name of Transform shape]
but “Account” + “from Order”


%u00b7 Use spaces into the shape names.


%u00b7 Use “_” [underscore] into the names of messages and variables and into the Ports and Port types.


Messages and variables (Orchestration view):


= “msg_” + schema name of this message without all namespace prefixes or .NET class 



For example: msg_ReportDiseases_request
if type of this message is PHSA.RCD.Orchestrations.ReportDiseases.ReportDiseasesService_.ReportDiseases_request


Note: it’s easy to set and maintain this name: just copy last part of it from Properties/Type field to Properties/Name field.


= “var_” + name



For example: var_XmlDocument
if type of this variable is System.Xml.XmlDocument .NET object


Note: it’s easy to set and maintain this name: just copy last part of it from Properties/Type field to Properties/Name field.


Note: we can use the message and variable names without prefixes like mentioned but it is more readable to use it.


Construct, Receive and Send shapes:


= name of constructed message (usually it is the schema of the message) without “msg_” prefix.



For example: ORU_Modified


Note: it’s easy to set and maintain this name: just copy part of it from Properties/Messages Constructed to Properties/Name. For example: From “msg_ORU_Modified” copy “ORU_Modified”


Transform shapes:


= “from “ + name of Source message



For example: from ORU


Note: it’s easy to set and maintain this name: just copy it (or part of it) from Properties/Input Messages to Properties/Name. For example: From “msg_ORU” copy “ORU”


Assignment shapes:


No strict rules, only advice:


Name it like the methods in classes. But cut a verb if it possible. Use “set” and “get” if it possible.



For example: “set segment OBX”


Other shapes:


Use the short names. They could fit the name space of the shapes.


 


Names of the Port shapes:


Notes:


%u00b7 The Port shapes are the real names! We can’t use spaces inside.


%u00b7 In the Orchestration view there are lists “Ports” and “Port types” that we have to distinguish the ports with different Communication directions and pattern into these lists.


%u00b7 We can’t use the same name for the ports and for the port types.



Rule for the Ports:















 

Send port


Receive port


Send-Receive port (Solicit-Response)


Receive-Send port (Request-Response)


Port:


S_ +


R_ +


SR_ +


RS_ +



Note: it’s easy to set and maintain this name: just copy it from Properties/Port type to Properties/Name. For example: From “S_Account_Type” copy “S_Account”



Rule for the Port types:


+ _Type


 


 


Does somebody have any comments? It would be realy appreciated…


 

Remove empty nodes in BizTalk by using XSLT

If you have ever had a map which begins to look unmanageable with tons of value mappings or extra functoids to simply manage empty nodes you don’t want in your output then you should consider using an XSLT mapping to clean the document up for you.

This involves actually making 2 mappings instead of one, but the upside is faster development with a nominal performance cost. Instead of adding functoids, testing and retesting the output, let the mapper generate the empty nodded and then add an extra mapping step with the following XSLT embedded in it:

<?xml version=”1.0″ ?>

<xsl:stylesheet xmlns:xsl=”@@ YOUR NAMESPACE @@” version=”1.0″ xmlns:ns0=”http://Stater.Isvcs.Iface.BO.GetLoanData.ElfV2″>

    <xsl:output method=”xml” indent=”yes” />

    <xsl:template match=”node()”>

        <xsl:if test=”count(descendant::text()[string-length(normalize-space(.))>0]|@*)”>

            <xsl:copy>

                <xsl:apply-templates select=”@*|node()” />

            </xsl:copy>

        </xsl:if>

    </xsl:template>

    <xsl:template match=”@*”>

        <xsl:copy />

    </xsl:template>

    <xsl:template match=”text()”>

        <xsl:value-of select=”normalize-space(.)” />

    </xsl:template>

</xsl:stylesheet>

Save this snippet (or download it here) into your project (open the XSLT and change the namespace!) then create a new map. Make your source and destination schemas the same and in the map properties add your XSLT in the “Custom XSLT path” setting. Place the new map after the “dirty” map; the output should give you an XML document free of extra nodes and a map free of extra functoids.

Of course, if you are doing a strictly messaging based implementation then you are out of luck unless you chain ports together but within an orchestration using XSLT to remove empty nodes might work well for you.

Tell us what you REALLY think about adapter development!

This is an open forum for gripes, complaints, suggestions, recommendations, and any other input you want to provide from your experience with Microsoft documentation regarding adapter development. Let it all hang out! I am compiling a list of items to work on for this new calendar year regarding custom adapter development and would love to hear what you REALLY think!