Friday, April 10, 2015

Exception Logging in K2

public class K2ExceptionHandler
    {
            System.Net.Mail.MailMessage expMail = null;
            System.Net.Mail.SmtpClient smtpClient = null;
            System.Net.Mail.MailAddress mailAddressFrom = null;
            Exception ex = null;
            object exContext = null;             
            string emailBody = string.Empty;
            bool bFlag = true;

            public void SendExceptionEmail(SourceCode.KO.ExceptionContext K2)
            {
            try
            {
                smtpClient = new System.Net.Mail.SmtpClient();

                expMail = new System.Net.Mail.MailMessage();

                //Mail To Address
                string mailTO = System.Configuration.ConfigurationManager.AppSettings["ExceptionEmailTo"]; // Get it from K2HostServer.exe.config file, located at "C:\Program Files (x86)\K2 blackpearl\Host Server\Bin"
                expMail.To.Add(mailTO);

                //Email From Address - Get it from String tabble
                string fromAddress = K2.StringTable["From Address"];
                mailAddressFrom = new System.Net.Mail.MailAddress(fromAddress);
                expMail.From = mailAddressFrom;

                //Email Subject
                expMail.Subject = "K2 Error: ProcessID " + K2.ProcessInstance.ID.ToString() + " for the Process, '" + K2.ProcessInstance.Process.FullName + "' is in error state";

                //Send HTML Email
                expMail.IsBodyHtml = true;
                expMail.Priority = System.Net.Mail.MailPriority.High;

                // Basic Message
                emailBody += "";
                emailBody += "";
                emailBody += "";
                emailBody += "";
                emailBody += "K2 Notification";
                emailBody += "
";
                emailBody += "";

                emailBody += ""
;
                emailBody += "
Dear Administrator,
";
                emailBody += "

";

                emailBody += "
"
+ " Error occurred in the K2 workflow, '" + K2.ProcessInstance.Process.FullName + "
' for the Process Intstance ID, '" + K2.ProcessInstance.ID.ToString() + "'. Below is a detailed extraction of the error and the process instance.";
                emailBody += "

";

                #region Process Instance Details

                emailBody += "
Process Intstance Details
";
                              
                emailBody += " " ;
                emailBody += "
"
;
                emailBody += ""
;

                emailBody += " " ;
                emailBody += "
ID:
";
                emailBody += "
"
+ K2.ProcessInstance.ID.ToString() + "
";
                emailBody += "
";

                emailBody += " " ;
                emailBody += "
Process Name:
";
                emailBody += "
"
+ K2.ProcessInstance.Process.FullName + "
";
                emailBody += "
";
               
                emailBody += " " ;
                emailBody += "
Folio:
";
                emailBody += "
"
+ K2.ProcessInstance.Folio + "
";
                emailBody += "
";
              
                emailBody += " " ;
                emailBody += "
Originator:
";
                emailBody += "
"
+ K2.ProcessInstance.Originator.DisplayName + "
";
                emailBody += "
";
                emailBody += " " ;
                emailBody += "
Start Date:
";
                emailBody += "
"
+ K2.ProcessInstance.StartDate.ToString() + "
";
                emailBody += "
";

                emailBody += "
";
                emailBody += "
";
                emailBody += "
";
                emailBody += "

";

                #endregion

                #region Process Data Fields
                emailBody += "
Data Field Values
";
                emailBody += " " ;
                emailBody += "
"
;
                emailBody += ""
;



                foreach (SourceCode.KO.DataField _dataField in K2.ProcessInstance.DataFields)
                {
                    emailBody += " " ;
                    emailBody += "
"
+ _dataField.Name + " [" + _dataField.FieldType.ToString() + "]
";
                    emailBody += "
"
+ _dataField.Value.ToString() + "
";
                    emailBody += "
";


                emailBody += "
";
                emailBody += "
";
                emailBody += "
";
                emailBody += "

";
                #endregion

                #region Failure Details
                emailBody += "
Failure Details
";
                emailBody += " " ;
                emailBody += "
"
;
                emailBody += ""
;

                //Check where the error happened
                switch (K2.ContextType)
                {
                    case SourceCode.KO.ContextType.ClientEvent:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.ClientEventContext)exContext).ActivityInstanceDestination.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Event Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.ClientEventContext)exContext).Event.Name + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.DestinationRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.DestinationRuleContext)exContext).ActivityInstance.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Destinations:
";
                            emailBody += "
"
;
                            foreach (SourceCode.KO.Destination _dest in ((SourceCode.KO.DestinationRuleContext)exContext).Destinations)
                            {
                                emailBody += " " + _dest.Name + " [" + _dest.Type.ToString() + "];";
                            }
                            emailBody += "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Slot Data:
";
                            emailBody += "
"
;
                            foreach (string _slotdata in ((SourceCode.KO.DestinationRuleContext)exContext).SlotInstanceData)
                            {
                                emailBody += " " + _slotdata + ";";
                            }
                            emailBody += "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Dynamic Queues:
";
                            emailBody += "
"
+ ((SourceCode.KO.DestinationRuleContext)exContext).DynamicQueues.ToString() + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Resolve queues to users:
";
                            emailBody += "
"
+ ((SourceCode.KO.DestinationRuleContext)exContext).ResolveQueuesToUsers.ToString() + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Single instance:
";
                            emailBody += "
"
+ ((SourceCode.KO.DestinationRuleContext)exContext).SingleInstance.ToString() + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Number of slots:
";
                            emailBody += "
"
+ ((SourceCode.KO.DestinationRuleContext)exContext).Slots.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.EscalationAction:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EscalationActionContext)exContext).ActivityInstance.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Redirect:
";
                            emailBody += "
"
+ ((SourceCode.KO.EscalationActionContext)exContext).Redirect.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.EscalationRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EscalationRuleContext)exContext).ActivityInstance.Activity.Name + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.EventEscalationAction:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventEscalationActionContext)exContext).EventInstance.ActivityInstanceDestination.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Event Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventEscalationActionContext)exContext).EventInstance.Event.Name + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.EventEscalationRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventEscalationRuleContext)exContext).EventInstance.ActivityInstanceDestination.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Event Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventEscalationRuleContext)exContext).EventInstance.Event.Name + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.EventSucceedingRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventSucceedingRuleContext)exContext).EventInstance.ActivityInstanceDestination.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Event Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventSucceedingRuleContext)exContext).EventInstance.Event.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Succeeding rule:
";
                            emailBody += "
"
+ ((SourceCode.KO.EventSucceedingRuleContext)exContext).SucceedingRule.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.IPCEvent:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.IPCEventContext)exContext).ActivityInstanceDestination.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Event Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.IPCEventContext)exContext).Event.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
IPC process:
";
                            emailBody += "
"
+ ((SourceCode.KO.IPCEventContext)exContext).Process + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
IPC connection string:
";
                            emailBody += "
"
+ ((SourceCode.KO.IPCEventContext)exContext).ConnectionString + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Synchronous:
";
                            emailBody += "
"
+ ((SourceCode.KO.IPCEventContext)exContext).Synchronous + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.LineRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Start activity name:
";
                            emailBody += "
"
+ ((SourceCode.KO.LineRuleContext)exContext).LineInstance.StartActivityInstance.Activity.Name + "
";
                            emailBody += "
";

                            //The folllowing throws error as it does not have finish activity details
                            //_emailBody += " ";
                            //_emailBody += "
Finish activity:
";
                            //_emailBody += "
" + ((SourceCode.KO.LineRuleContext)_exContext).LineInstance.FinishActivityInstance.Activity.Name + "
";
                            //_emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Line name:
";
                            emailBody += "
"
+ ((SourceCode.KO.LineRuleContext)exContext).LineInstance.Line.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Line rule:
";
                            emailBody += "
"
+ ((SourceCode.KO.LineRuleContext)exContext).LineRule.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.PrecedingRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity name:
";
                            emailBody += "
"
+ ((SourceCode.KO.PrecedingRuleContext)exContext).ActivityInstance.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Preceeding rule:
";
                            emailBody += "
"
+ ((SourceCode.KO.PrecedingRuleContext)exContext).PrecedingRule.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.ProcessEscalationAction:
                    case SourceCode.KO.ContextType.ProcessEscalationRule:
                    case SourceCode.KO.ContextType.ProcessFinishRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.ProcessStartRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Message:
";
                            emailBody += "
"
+ ((SourceCode.KO.ProcessStartRuleContext)exContext).Message + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Start rule:
";
                            emailBody += "
"
+ ((SourceCode.KO.ProcessStartRuleContext)exContext).Start.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.ServerEvent:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.ServerEventContext)exContext).ActivityInstanceDestination.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Event Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.ServerEventContext)exContext).Event.Name + "
";
                            emailBody += "
";

                            break;
                        }
                    case SourceCode.KO.ContextType.StartRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.StartRuleContext)exContext).ActivityInstance.Activity.Name + "
";
                            emailBody += "
";
                            break;
                        }
                    case SourceCode.KO.ContextType.SucceedingRule:
                        {
                            emailBody += " " ;
                            emailBody += "
Error thrown by:
";
                            emailBody += "
"
+ K2.ContextType.ToString() + "
";
                            emailBody += "
";

                            exContext = K2.ContextObject;
                            emailBody += " " ;
                            emailBody += "
Activity Name:
";
                            emailBody += "
"
+ ((SourceCode.KO.SucceedingRuleContext)exContext).ActivityInstance.Activity.Name + "
";
                            emailBody += "
";

                            emailBody += " " ;
                            emailBody += "
Succeeding rule:
";
                            emailBody += "
"
+ ((SourceCode.KO.SucceedingRuleContext)exContext).SucceedingRule.ToString() + "
";
                            emailBody += "
";
                            break;
                        }
                    default:
                        {
                            emailBody += "
colspan=\"2\">No details available
";
                            break;
                        }
                }

                emailBody += "
";
                emailBody += "
";
                emailBody += "
";
                emailBody += "

";
                #endregion

                #region Exception Details
                emailBody += "
Exception Details
";
                emailBody += " " ;
                emailBody += "
"
;
                emailBody += ""
;

                ex = new Exception("NOTHING");
                ex = (Exception)K2.ExceptionObject;
                bFlag = true;
                while (bFlag == true)
                {
                    if (ex.InnerException != null)
                    {
                        ex = ex.InnerException;
                    }
                    else
                    {
                        emailBody += " " ;
                        emailBody += "
Message:
";
                        emailBody += "
"
+ ex.Message + "
";
                        emailBody += "
";

                        emailBody += " " ;
                        emailBody += "
Stack Trace:
";
                        emailBody += "
"
+ ex.StackTrace + "
";
                        emailBody += "
";
                        bFlag = false;
                    }
                }
               
                emailBody += "
";
                emailBody += "
";
                emailBody += "
";
              
                #endregion

                

                #region View Flow link

                string K2ServerName = string.Empty;

                //Workflow Management Server
                string strWorkflowServer = K2.StringTable["Workflow Server"]; //Integrated=True;IsPrimaryLogin=True;Authenticate=True;EncryptedPassword=False;Host=dlx;Port=5252
                string[] workflowServerDetails = strWorkflowServer.Split(';');
                foreach (string strWorkflowServerDetail in workflowServerDetails)
                {
                    if (strWorkflowServerDetail.Contains("Host"))
                    {
                        K2ServerName = strWorkflowServerDetail.Substring(strWorkflowServerDetail.IndexOf('=') + 1);
                    }
                }

                string strViewFlowURL = @"http://###K2Server###:81/ViewFlow/ViewFlow.aspx?ViewTypeName=ProcessView&K2Server=###K2Server###:5252&HostServerName=###K2Server###&HostServerPort=5555&ProcessID=###ProcinstID###";
                strViewFlowURL = strViewFlowURL.Replace("###K2Server###", K2ServerName);
                strViewFlowURL = strViewFlowURL.Replace("###ProcinstID###", K2.ProcessInstance.ID.ToString());

                string strViewFlowLink = "<" + "a href='" + strViewFlowURL + "' target=_blank>Click Here
";
                emailBody += "

";
                emailBody += "
To open the K2 View Flow, "
+ strViewFlowLink + ".
";
                emailBody += "

";
                #endregion


                emailBody += "
Regards,
";
                emailBody += "
K2 Exception Handler
";
                emailBody += "
";
                emailBody += "
";
                emailBody += "
";

                expMail.Body = emailBody;

                #region Send Email

                string smtpMailServer = K2.StringTable["Mail Server"]; //Get mail server from String table

                using (smtpClient as IDisposable)
                {

                    if (smtpMailServer.IndexOf(":") == -1)
                    {
                        smtpClient.Host = smtpMailServer;
                    }
                    else
                    {
                        string[] connection = smtpMailServer.Split(new Char[] { ':' });

                        Int32 I = 0;

                        if (string.IsNullOrEmpty(connection[0]) || string.IsNullOrEmpty(connection[1]))
                        {
                            throw new Exception("Invalid SMTP Server / Port arguments supplied.");
                        }

                        // PORT 2ND PARM ONLY!
                        if (Int32.TryParse(connection[1], out I))
                        {
                            smtpClient.Host = connection[0];
                            smtpClient.Port = Int32.Parse(connection[1]);
                        }
                        else
                        {
                            throw new Exception("Invalid SMTP Server / Port arguments supplied.");
                        }
                    }
                    using (expMail)
                    {
                        smtpClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
                        smtpClient.UseDefaultCredentials = true;
                        smtpClient.Send(expMail);                       
                    }
                }
                #endregion
            }
            catch (Exception expMail)
            {
                //Console.WriteLine("[Process Error Notify] Error sending email: " + exMail.Message); //todo Log error to Sharepoint Logs
            }
            finally
            {
                expMail = null;
                smtpClient = null;
                mailAddressFrom = null;
                throw ((Exception)K2.ExceptionObject);
            }
        }

    }