Wednesday, June 1, 2011

Object reference not set to an instance of an object + BizTalk

Recently my team mate reported me an issue in his BizTalk application..
application does something like it gets the request from MSMQ then makes Database call get response from database and then write response to the response_MSMQ.

following is the error in eventlog:

Uncaught exception (see the 'inner exception' below) has suspended an instance of service (d18ebb96-bf15-bdd9-06f5-d2c07b2b4260)'.
The service instance will remain suspended until administratively resumed or terminated.
If resumed the instance will continue from its last persisted state and may re-throw the same unexpected exception.
InstanceId: 3e6974ee-1506-4eea-abcf-7c7b18cadf1b
Shape name:
ShapeId: 00000000-0000-0000-0000-000000000000
Exception thrown from: segment 19, progress 10
Inner exception: Object reference not set to an instance of an object.

Exception type: NullReferenceException
Source: ADDRECEIPTS_IN
Target Site: Microsoft.XLANGs.Core.StopConditions segment19(Microsoft.XLANGs.Core.StopConditions)
The following is a stack trace that identifies the location where the exception occured

at <>.segment19(StopConditions stopOn)
at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, S


There are two things I noticed :
1. When you look at the the Orchestration debugger for the the message it shows the message is sent to Database and no response is received fron SQL,, but certainly thats not the case as BizTalk has a concepts of persistance points, where it persists the state of orchestration at certain events of message flow, in my case it is the Send port by which I am sending message to database causes persistance.. and therefore it is showing me message flow till send shape. and after inspecting more a bit I concluded there in nothing wrong in response message from database. So definately something is going wrong between the sql send shape and the next persitance point.
So hereby is the problem with the code, where a .NET component is call and that piece of code is throwing this error. Hence, whenever you get this kind of error
a) make sure your are getting correct response message and it should'nt be null or something.
b) Look for the code there must be something which is screwing the stuff but deviating you from the issue root.

2) In case, I would have got this issue in first Activating Receive shape in orchestration, let me go to little back, when we create orchestration we define certain orchetration variable as well, as per the our business functionality.knowing the fact everything in BizTalk compiles to .NET code, If we try to assume an orchestration as class and Orchestration variables as class variables and when got this issue..Then I suggest to look at the code of constructors of orchestration variable defined types. there must be something wrong there.

Moral of the story: Handle exceptions properly and test exceptional handling, this is one of few things in programmers life which can soothe his burning @$$

Thursday, January 13, 2011

WMI Scripts + BizTalk

Recently, I moved into new BizTalk assigment and I was very happy but my happiness shattered completely as the Architecture was completely screwed up (I apologies, being 4+ yrs of exp, I don't hold qualification to comment anything on architecture but personall speaking it was screwed up :( ).

It was something like integrating 16 messages and without using any percentage of brain, people have created 16 orchestrations and that to in 16 different BizTalk projects. uff.. this made me remember my first year of career when I used to do POCs and its giving me the feeling they as well doing POCs and then moving their POCs to UAT server and finally to test server.

But truly speaking, they have a valid reason i.e. "Time constraint" so they haven't wasted single second for investigation and finally it ended-up in 12-14 hrs daily in office, effort shoot up by 200+%.

And this is not enough, to add further happiness I got the wonderful surprise on the next day itself, that the other guy is moving out and I have to carry forward the remaining development and production deployment. Soon I realized deployment will going to be real pain in a$$.



I left with 2 options: first resigning from the company, secondly to do something that will largely help me, I am not much worried for anything else.


So, I thought of doing deployment programatically i.e. using WMI.
Following are the task, I am going to achieve by deployment application:
1. Creating Host (3 Host)
2. Creating Host Instance (3 Host Instance)
3. Adding Send Handler (for 4 Adapters)
4. Adding Receive Handler (for 3 Adapters)
5. Creating BizTalk Application (4 New applications)
6. Adding Reference to applications (few numbers)
7. Installing BizTalk Assemblies (16+)
8. Loading Binding files (16+)
9. Few more minor activities.

Frankly speaking, If I have to do these many task I would rather prefer to quit my job and look for the new one.

The day I have finished my the coding for deployment, I cried tears of joy :)

WMI Application extensively uses:
System.Management namespace

So keeping this Bullshit aside let go straight to the code :

public partial class HostingTask
{
#region CONSTANTS
private const string WMI_Root = @"root\MicrosoftBizTalkServer";
private const string MSBTS_HostSetting = "MSBTS_HostSetting";
private const string MSBTS_ServerHost = "MSBTS_ServerHost";
private const string MSBTS_HostInstance = "MSBTS_HostInstance";
private const string MSBTS_AdapterSetting = "MSBTS_AdapterSetting";
private const string MSBTS_ReceiveHandler = "MSBTS_ReceiveHandler";
private const string MSBTS_SendHandler2 = "MSBTS_SendHandler2";
#endregion

private ManagementClass mgmtClass;
private ManagementObject mgmtObj;

#region AddHost Method :- This Method creates a Logical host in BizTalk Group
public void AddHost(BTHost host)
{
try
{

Console.WriteLine("Creating Host - " + host.HostName);
PutOptions options = new PutOptions();
options.Type = PutType.CreateOnly;
//create a ManagementClass object and spawn a ManagementObject instance
mgmtClass = new ManagementClass(WMI_Root, MSBTS_HostSetting, null);
if (!Exists(mgmtClass, "Name", host.HostName))
{
mgmtObj = mgmtClass.CreateInstance();
//set the properties for the Managementobject
mgmtObj["Name"] = host.HostName;
mgmtObj["HostType"] = host.HostType;
mgmtObj["NTGroupName"] = host.NTGroupName;
mgmtObj["AuthTrusted"] = host.AuthenticationTrusted;
mgmtObj["HostTracking"] = host.AllowHostTracking;
//create Host
mgmtObj.Put(options);
Console.WriteLine("Host - " + host.HostName + " - has been created successfully");
}
else
{
Console.WriteLine("BOSS.. Host - " + host.HostName + " - already in place.. why the hell you are wasting my time.");
}
}
catch (Exception ex){
Console.WriteLine("CreateHost - " + host.HostName + " - failed. I do expect people to do some part of his/her job. Anyway following is the exception message : " + ex);
throw;
}

}
#endregion


#region RemoveHost Method :- This Method Deletes a logical host from BizTalk Group
public void RemoveHost(string hostName)
{
try{
Console.WriteLine("Removing Host : " + hostName);
mgmtClass = new ManagementClass(WMI_Root, MSBTS_HostSetting, null);
if (Exists(mgmtClass, "Name", hostName))
{
mgmtObj = mgmtClass.CreateInstance();
mgmtObj["Name"] = hostName;
mgmtObj.Delete();
Console.WriteLine(hostName + "Host removed successfully");
}
else
{
}
}
catch {
throw;
}
}
#endregion


#region AddHostInstance :- This Method created the Host Instance on the physical server
public void AddHostInstance(BTHostInstance hostIns, string hostName)
{
try
{
if (hostIns.Server == null hostIns.Server == string.Empty)
{
hostIns.Server = Environment.MachineName;
}
Console.WriteLine("Creating Host Instance : " + hostName + "on Server : " + hostIns.Server);
//Creating instance of BizTalk Host.
mgmtClass = new ManagementClass(WMI_Root, MSBTS_ServerHost, null);
mgmtObj = mgmtClass.CreateInstance();
mgmtObj["ServerName"] = hostIns.Server;
mgmtObj["HostName"] = hostName;
//Map HostInstance to be created with the Host
mgmtObj.InvokeMethod("Map", null);
mgmtClass = new ManagementClass(WMI_Root, MSBTS_HostInstance, null);
mgmtObj = mgmtClass.CreateInstance();
mgmtObj["Name"] = "Microsoft BizTalk Server " + hostName + " " + hostIns.Server;
object[] objparams = new object[3];
objparams[0] = hostIns.Logon.Username;
objparams[1] = hostIns.Logon.Password;
objparams[2] = true;
//Create Host Instance
mgmtObj.InvokeMethod("Install", objparams);

Console.WriteLine("Host Instance " + mgmtObj["Name"] + " created.");
}
catch{
throw;
}
}
#endregion


#region RemoveHostInstance Method :- This Method deletes a Host Instance from the server and BizTalk Group
public void RemoveHostInstance(BTHostInstance hostIns, string hostName)
{
try
{
string hostInstanceName = "Microsoft BizTalk Server" + " " + hostName + " " + hostIns.Server;
Console.WriteLine("Removing Host Instance : " + hostInstanceName);
ManagementClass mgmtClass = new ManagementClass(WMI_Root, MSBTS_HostInstance, null);
ManagementObjectCollection hostInstanceCollection = mgmtClass.GetInstances();
ManagementObject mgmtObj = null;
foreach (ManagementObject instance in hostInstanceCollection)
{
if (instance["Name"].ToString().ToUpper() == hostInstanceName.ToUpper())
{
mgmtObj = instance;
}
}
if (mgmtObj == null)
return;
if (mgmtObj["HostType"].ToString() != "2" && mgmtObj["ServiceState"].ToString() == "4")
{
//If HostInstance is not stopped.. Stop it or is instance of type IsolatedHost
mgmtObj.InvokeMethod("Stop", null);
}
//Remove Host Instance
mgmtObj.InvokeMethod("UnInstall", null);
ManagementClass svrHostClass = new ManagementClass(WMI_Root, MSBTS_ServerHost, null);
ManagementObject svrHostObject = svrHostClass.CreateInstance();
svrHostObject["ServerName"] = hostIns.Server;
svrHostObject["HostName"] = hostName;
//Unmap Host-instance from Host
svrHostObject.InvokeMethod("UnMap", null);
Console.WriteLine("Host Instance : " + hostInstanceName + " removed Sucessfully");
}
catch
{
throw;
}
}
#endregion


#region AddSendHandler Method :- This method Adds the send handler for an Adapter
public void AddSendHandler(string adapterName, string handler)
{
try
{
Console.WriteLine("Adding Send Handler : " + handler + " to " + adapterName + " Adapter.");
ManagementClass mgmtClass = new ManagementClass(WMI_Root, MSBTS_SendHandler2,null);
if (!Exists(mgmtClass, "HostName", handler, "AdapterName", adapterName))
{
mgmtObj = mgmtClass.CreateInstance();
mgmtObj.SetPropertyValue("AdapterName", adapterName);
mgmtObj.SetPropertyValue("HostName", handler);
mgmtObj.Put();
Console.WriteLine("Send Handler : " + handler + " added to " + adapterName + " Adapter.");
}
else
{
}
}
catch
{
throw;
}
}
#endregion


#region RemoveSendHandler Method :- This method removes the send handler for an Adapter
public void RemoveSendHandler(string adapterName, string handler)
{
try
{

Console.WriteLine("Removing Send Handler : " + handler + " from " + adapterName + " Adapter.");
mgmtClass = new ManagementClass(WMI_Root, MSBTS_SendHandler2, null);
if (Exists(mgmtClass, "HostName", handler, "AdapterName", adapterName))
{
mgmtObj = mgmtClass.CreateInstance();
mgmtObj.SetPropertyValue("AdapterName", adapterName);
mgmtObj.SetPropertyValue("HostName", handler);
mgmtObj.Delete();
Console.WriteLine("Send Handler : " + handler + " removed from " + adapterName + " Adapter.");
}
else
{

}
}
catch
{
throw;
}
}
#endregion


#region AddReceiveHandler Method :- This method Adds the receive handler for an Adapter
public void AddReceiveHandler(string adapterName, string handler)
{
try
{
Console.WriteLine("Adding Receive Handler : " + handler + " to " + adapterName + " Adapter.");
mgmtClass = new ManagementClass(WMI_Root, MSBTS_ReceiveHandler, null);
if (!Exists(mgmtClass, "HostName", handler, "AdapterName", adapterName))
{
mgmtObj = mgmtClass.CreateInstance();
mgmtObj.SetPropertyValue("AdapterName", adapterName);
mgmtObj.SetPropertyValue("HostName", handler);
mgmtObj.Put();
Console.WriteLine("Receive Handler : " + handler + " added to " + adapterName + " Adapter.");
}
else
{
}
}
catch
{
throw;
}
}
#endregion


#region RemoveReceiveHandler Method :- This Method removes the receive handler for an Adapter
public void RemoveReceiveHandler(string adapterName, string handler)
{
Console.WriteLine("Removing Receive Handler : " + handler + " from " + adapterName + " Adapter.");
mgmtClass = new ManagementClass(WMI_Root, MSBTS_ReceiveHandler, null);
if (Exists(mgmtClass, "HostName", handler, "AdapterName", adapterName))
{
mgmtObj = mgmtClass.CreateInstance();
mgmtObj.SetPropertyValue("AdapterName", adapterName);
mgmtObj.SetPropertyValue("HostName", handler);
mgmtObj.Delete();
Console.WriteLine("Receive Handler : " + handler + " added to " + adapterName + " Adapter.");
}
else
{
}
}
#endregion


#region Exists Method :- This method checks the presence of Management object
private bool Exists(ManagementClass cls, string key , string val)
{
ManagementObjectCollection objcoll = cls.GetInstances();
foreach(ManagementObject obj in objcoll)
{
if (obj[key].ToString().ToUpper() == val.ToUpper())
return true;
}
return false;
}
#endregion


#region Exists Method :- This method checks the presence of Management object
private bool Exists(ManagementClass cls, string key, string val,string key1, string val1)
{
ManagementObjectCollection objcoll = cls.GetInstances();
foreach (ManagementObject obj in objcoll)
{
if (obj[key].ToString().ToUpper() == val.ToUpper() && obj[key1].ToString().ToUpper() == val1.ToUpper())
return true;
}
return false;
}
#endregion
}