What’s New in BizTalk Server 2013 R2?

Support for:

• Windows Server 2012 R2, Windows Server 2012, Windows 8.1, Windows 7 SP1.

• Microsoft Office Excel 2013 or 2010.

• .NET Framework 4.5 and .NET Framework 4.5.1

• Visual Studio 2013

• SQL Server 2014 or SQL Server 2012 SP1

• SharePoint 2013 SP1

• WCF-WebHttp adapter now supports sending and receiving JSON messages. 

• SFTP adapter now supports two-factor authentication

 

Windows Azure Mobile Services for Windows 8 and Windows Phone 8

If you are looking to develop Windows apps with Azure Mobile Services, this book is a good choice. This book will take you from the start to finish in setting up your artifacts in Azure and make the whole process seem easy! This book is at a beginner to intermediate level.

It covers both Windows Phone 8 and Windows 8 apps. Apart from the how-to’s, this book also covers best practices across various aspects of the app building with Azure. Other things covered include security, push notifications etc. Highly recommended!

Powershell script to administer messages in BizTalk

The below script does everything from resume to terminate the suspended messages. It also allows you to get counts and save suspended messages into dedicated folders.

# Script to save, resume and list suspended messages. To be used by BizTalk admin ONLY!
# Created on 30/01/2014 by Dipesh A.
# Commands:
   # Note: CD to script path first.

    # To get count of all suspended messages
    # PS > .\GetSuspended.ps1 -action counts

    # To list all suspended messages
    # PS > .\GetSuspended.ps1 -action list

    # To save all suspended messages
    # PS> .\GetSuspended.ps1 -action save -path 'X:\[Path]'

    # To resume resumable suspended messages
    # PS> .\GetSuspended.ps1 -action resume

    # To terminate non-resumable suspended messages
    # PS> .\GetSuspended.ps1 -action terminate

# -----------------------------------------------------------------

# declare params: the action to take, and an optional
# path to save messages to
#
param(
    [string] $action=$(throw 'need action'),
    [string] $path=$(if ($action -eq 'save') { throw 'need path' })
)

#
# get all suspended messaging service instances,
# both resumable and not-resumable
#
function bts-get-messaging-svc-instances()
{
    get-wmiobject MSBTS_ServiceInstance `
    -namespace 'root\MicrosoftBizTalkServer' `
    -filter '(ServiceClass=1 or ServiceClass=4) and ServiceStatus = 4'
}

#

# save the message associated to the
# specified messaging Service Instance
#
function bts-save-message([string]$msgid, [string]$sname, $homepath)
{

    #save each message within respective folders.

    "msgid is $msgid"
    "ServiceName is $sname"
    "msg_counter is $counter"
    $msg = get-wmiobject MSBTS_MessageInstance `
    -namespace 'root\MicrosoftBizTalkServer' `
    -filter "ServiceInstanceID = '$msgid'"

    $newpath = (Join-Path $homepath $sname)
    "new path is $newpath"

    $r_code= (test-path $newpath)
    "return code is $r_code"

    if ($r_code -eq $False)
       {
       md $newpath
       "new directory created"
    }

    foreach($m in $msg)
    {
       $m.psbase.invokemethod('SaveToFile', ($newpath))
       "Message from ServiceInstanceID=$msgid saved to $newpath."
   }

}

#
# save the message associated to the
# specified messaging Service Instance
#
function bts-save-message1([string]$msgid)
{

    $msg = get-wmiobject MSBTS_MessageInstance `
    -namespace 'root\MicrosoftBizTalkServer' `
    -filter "ServiceInstanceID = '$msgid'"
    $msg.psbase.InvokeMethod('SaveToFile', ($path))
    "Message from ServiceInstanceID=$msgid saved."
}

#
# list resumable suspended instances
#
function bts-get-resumable-suspended()
{
    get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter 'ServiceStatus=4'
}

#
# list resumable suspended instances
#
function bts-get-nonresumable-suspended()
{
    get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter 'ServiceStatus=32'
}

#
# resume instance
#
function bts-resume-instance([string]$msgId)
{
    if(!($msgId -eq “”))
    {
       "Resume {0}" -f $msgId
       $msg = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter “InstanceID = '$msgId'”
       $msg.Resume() | Out-Null
    "- Done"
    }
    else
    {
       "MessageId missing"
    }
}

#
# terminate non resumable instance
#
function bts-terminate-instance([string]$msgId)
{
    if(!($msgId -eq “”))
    {
       "Terminate {0}" -f $msgId
       $msg = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter “InstanceID = '$msgId'”
       $msg.Terminate() | Out-Null
       "- Done"
   }
   else
    {
       "MessageId missing"
   }
}

#
# main script
#
switch ( $action )
{
    'counts' {
       bts-get-messaging-svc-instances |
       %{ $counter++; }

       "Total: $counter"

       $counterrr = 0
       bts-get-resumable-suspended | %{ $counterrr++; }

       "Resumable: $counterrr"

       $counternr = 0
       bts-get-nonresumable-suspended | %{ $counternr++; }

       "Non resumable: $counternr"
    }

   'list' {
        bts-get-messaging-svc-instances |
       fl InstanceId, ServiceName, SuspendTime, HostName,
       ServiceStatus, ErrorId, ErrorDescription
    }
    'save'
    {

       #Set home path
       $timestamp = Get-Date -UFormat "%Y%m%d%H%M%S"
       $newpath = (Join-Path $path $timestamp)
       "Home path is $newpath"

       $r_code= (test-path $newpath)
       "return code is $r_code"

       if ($r_code -eq $False)
       {
          md $newpath
          "new directory created"
       }

        #save summary
       $wmi = get-wmiobject MSBTS_ServiceInstance `
       -namespace 'root\MicrosoftBizTalkServer' `
       -filter '(ServiceClass=1 or ServiceClass=4) and ServiceStatus = 4' | out-string

       $file = New-Item -Type File -Name "Summary.txt" -Path $newpath
       Add-Content $file -Value $wmi

       bts-get-messaging-svc-instances |
       %{ $counter++; bts-save-message $_.InstanceID $_.ServiceName $newpath }

    }
    'resume'
    {
      bts-get-resumable-suspended | %{ bts-resume-instance($_.InstanceID) }
    }
    'terminate'
    {
      bts-get-nonresumable-suspended | %{ bts-terminate-instance($_.InstanceID) }
    }
}

ESB Portal with a bulk resubmission feature

The OTB ESB portal is quite handy but lacks some useful features and also has some usability issues.

I recently had a go at enhancing the ESB Management Portal so that messages can be resubmitted in bulk. This needed a bit of web skills as well in order to cater for the UI and make the whole experience seemless.
I needed to introduce two modes in the ‘Faults’ page where the user could view pending faults vs processed faults.

screen1

Users could select the faults for which they wanted the messages to be resubmitted and click on Resubmit.

screen2

Messages would then be resubmitted in the order same order they were thrown as exceptions.

screen3

This has really helped us in scenarios where a whole load of messages would be sent to the ESB portal for review and the administrator has to ensure that order of processing was maintained.

This feature involved changes to both the portal and the ESB exception service. The portal was also “ajaxified” for a better user experience.

BizTalk 2013 Licensing – cheaper? Maybe, maybe not!

Note this is not the official Licensing document for BizTalk Server! Please consult Microsoft before making any purchase decisions.

Overview

With the BizTalk 2013 (english locale) SKUs hitting the Microsoft sites for purchase in April. It is important to note an important change Microsoft have made to the BizTalk 2013 licensing model. Up till now (i.e. BizTalk 2010), BizTalk followed a per processor model (ie a physical socket) . With BizTalk 2013, Microsoft have changed the model to be per core. Just like SQL Server.

But what does core licensing mean? How does it affect your costs? For this, one must understand the concept of a core.

As per the wiki, a core is a central processing unit within a processor. So a dual core processor would have 2 cores, a quad core would have 4 cores and so on.

The above is a dual core processor with 2 cores.

The per processor model of licensing has its own problems. One could buy a processor license for a quad core processor and still end up paying for one processor and get the processing power of 4 processors. With the new model, a license has to be purchased for every core. That is 4 licenses would be required in this particular example. Core prices are costed as the 1/4 of the processor license cost.

Lets do some cost analysis between the two model for the same spec (prices are approx):

Per Processor (quad-core): ~$40,000 x 1 = ~$40,000

Per Core (quad-core):  ~$10,000 x 4 = ~$40,000

From the above, there is not much difference in this example. However, if you ended up using 5 cores for argument sake, what do the numbers look like between the two models?

Per Processor (quad-core + single core): ~$40,000 x 2 = ~$80,000

Per Core (quad-core + single core):  ~$10,000 x 5 = ~$50,000

There you have significant cost savings for almost $30,000 with the new model!

Some Key-points

  • All the cores in the server must be licensed.
  • Licenses can be purchased in pack of two.
  • Minimum of 4 core licenses required (if your server has less than 4 cores, ex: single core and dual core machines)
  • Actual number of core licenses required may vary based on processor type and core factor.

Prices

The estimated price for a core license is approximately $10,835 for Enterprise and $2,485 for Standard.

How do you calculate the cores?

In order to calculate the cores, core-factor must be understood. A core-factor is different for different brands of processors.

Type Core-factor
Single Core 4
Dual Core 2
AMD processors (6 cores or above) 0.75
All others 1

So if you were using a 12 core AMD processor, the license cost would be calculated as follows:

AMD: 12 cores x 0.75 = 9 core licenses required.

Intel: 12 cores x 1 = 12 core licenses required.

Conclusion

From the above, it is apparent that the licensing costs entirely depend on how BizTalk Server is deployed and the type of hardware. It affects different companies in different ways.

BAM_AN packages not executing by SQL jobs

I recently hit an issue with the BAM_AN packages executed through a SQL job  failing with the following message.

Object reference not set to an instance of an object.

at…. UpdateDataSourceAndGetAnnotation(String cubeName, String asServerName, String asDatabaseName, String ssServername, String ssDatabaseName)  

The reason was the account under which my SQL jobs were running did not have access to the Analysis Services. Solution was to right click on the root node –> properties and add the account under the security tab and it started working.

BAM: Regenerating data for non-RTA views

If you have log-shipped or moved your BAM databases to another environment, you might find that the legacy data in your non-rta view vanishes and only recent data is displayed.

This defeats the purpose of having scheduled aggregations to view data over months. However, there is a way to “reset” your cubes.

In the BAMPrimaryImport database, there is a table called ‘bam_Metadata_AnalysisTasks’. This table keeps track of range of records that the cube processed each time it ran. This range is also used to define the view ‘bam_<cubename>_CompletedInstancesWindow’ that is used to populated the staging tables for aggregation.

The trick is to delete all the records from this table in the BAMPrimaryImport database.

Delete from bam_Metadata_AnalysisTasks where CubeName=’<cubename>’

GO

Insert INTO bam_Metadata_AnalysisTasks(CubeName,MinRecordID,MaxRecordID,LastStartTime,LastEndTime)

VALUES (‘<cubename>’,NULL,NULL,NULL,NULL)

Note: Run the above queries for all the cubes in question. DO NOT RUN IN PROD BEFORE TESTING.

After executing the above command, run the corresponding BAM_AN_<cubename> package. After this has completed, browse to the BAM portal and you will see all historical data again.

Cheers.