private void ExecuteScript( DialPlanExecutingScript executingScript, DialPlanContext dialPlanContext, DialPlanScriptFacade planFacade, string script) { try { Thread.CurrentThread.Name = "dialplanscript-" + executingScript.ScriptNumber; if (m_impersonationUsername != null && m_impersonationPassword != null) { WrapperImpersonationContext impersonationConext = new WrapperImpersonationContext(null, m_impersonationUsername, m_impersonationPassword); impersonationConext.Enter(); } //logger.Debug(Thread.CurrentThread.Name + " identity=" + WindowsIdentity.GetCurrent().Name + "."); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution starting on thread " + Thread.CurrentThread.Name + " for " + dialPlanContext.Owner + ".", null)); executingScript.DialPlanScriptEngine.Execute(script, executingScript.DialPlanScriptScope); //FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution finished after full script run on thread " + Thread.CurrentThread.Name + " for " + dialPlanContext.Owner + ".", null)); } catch (ApplicationException appExcp) { if (appExcp.Message != "Script was halted by external intervention.") { logger.Error("ApplicationException ExecuteScript. " + appExcp.Message); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was an exception executing your dial plan script: " + appExcp.Message, executingScript.Owner)); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "ApplicationException on user " + executingScript.Owner + "'s dial plan script. " + appExcp.Message, null)); executingScript.ExecutionError = appExcp.Message; } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution finished after being halted due to execution interrupt on thread " + Thread.CurrentThread.Name + " for " + dialPlanContext.Owner + ".", null)); } } //catch (System.Scripting.SyntaxErrorException) catch (SyntaxErrorException syntaxExcp) { logger.Warn("SyntaxErrorException. Owner=" + dialPlanContext.Owner + ", DialPlanName=" + dialPlanContext.SIPDialPlan.DialPlanName + ", Line=" + syntaxExcp.Line + "."); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was a syntax error in your dial plan on line " + syntaxExcp.Line + ", please check.", executingScript.Owner)); executingScript.ExecutionError = "Dial plan syntax error"; } catch (MissingMethodException missingExcp) { logger.Warn("MissingMethodException. " + missingExcp.Message); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was a missing method exception in your dial plan: " + missingExcp.Message + ".", executingScript.Owner)); executingScript.ExecutionError = "Dial plan missing method"; } catch (ThreadAbortException) { } catch (Exception excp) { logger.Error("Exception ExecuteScript (" + excp.GetType() + "). " + excp.Message); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was an exception executing your dial plan script: " + excp.Message, executingScript.Owner)); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Exception on user " + executingScript.Owner + "'s dial plan script (" + excp.GetType() + "). " + excp.Message, null)); executingScript.ExecutionError = "Dial plan exception"; } finally { executingScript.StopExecution(); } }
private void ExecuteScript( DialPlanExecutingScript executingScript, DialPlanContext dialPlanContext, DialPlanScriptFacade planFacade, string script) { try { Thread.CurrentThread.Name = "dialplanscript-" + executingScript.ScriptNumber; if (m_impersonationUsername != null && m_impersonationPassword != null) { WrapperImpersonationContext impersonationConext = new WrapperImpersonationContext(null, m_impersonationUsername, m_impersonationPassword); impersonationConext.Enter(); } //logger.Debug(Thread.CurrentThread.Name + " identity=" + WindowsIdentity.GetCurrent().Name + "."); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution starting on thread " + Thread.CurrentThread.Name + " for " + dialPlanContext.Owner + ".", null)); executingScript.DialPlanScriptEngine.Execute(script, executingScript.DialPlanScriptScope); //FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution finished after full script run on thread " + Thread.CurrentThread.Name + " for " + dialPlanContext.Owner + ".", null)); } catch (ApplicationException appExcp) { if (appExcp.Message != "Script was halted by external intervention.") { logger.Error("ApplicationException ExecuteScript. " + appExcp.Message); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was an exception executing your dial plan script: " + appExcp.Message, executingScript.Owner)); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "ApplicationException on user " + executingScript.Owner + "'s dial plan script. " + appExcp.Message, null)); executingScript.ExecutionError = appExcp.Message; } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution finished after being halted due to execution interrupt on thread " + Thread.CurrentThread.Name + " for " + dialPlanContext.Owner + ".", null)); } } //catch (System.Scripting.SyntaxErrorException) catch (SyntaxErrorException syntaxExcp) { logger.Warn("SyntaxErrorException. Owner=" + dialPlanContext.Owner + ", DialPlanName=" + dialPlanContext.SIPDialPlan.DialPlanName + ", Line=" + syntaxExcp.Line + "."); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was a syntax error in your dial plan on line " + syntaxExcp.Line + ", please check.", executingScript.Owner)); executingScript.ExecutionError = "Dial plan syntax error"; } catch (MissingMethodException missingExcp) { logger.Warn("MissingMethodException. " + missingExcp.Message); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was a missing method exception in your dial plan: " + missingExcp.Message + ".", executingScript.Owner)); executingScript.ExecutionError = "Dial plan missing method"; } catch (ThreadAbortException) { } catch (Exception excp) { logger.Error("Exception ExecuteScript (" + excp.GetType() + "). " + excp.Message); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "There was an exception executing your dial plan script: " + excp.Message, executingScript.Owner)); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Exception on user " + executingScript.Owner + "'s dial plan script (" + excp.GetType() + "). " + excp.Message, null)); executingScript.ExecutionError = "Dial plan exception"; } finally { executingScript.StopExecution(); } }
private void MonitorScripts() { try { while (!StopScriptMonitoring) { DialPlanExecutingScript[] killScripts = null; bool lockTaken = false; Monitor.TryEnter(m_runningScripts, 100, ref lockTaken); if (lockTaken) { try { killScripts = (from script in m_runningScripts where script.Complete || DateTime.Now > script.EndTime || DateTime.Now.Subtract(script.StartTime).TotalSeconds > ABSOLUTEMAX_SCRIPTPROCESSING_SECONDS select script).ToArray(); } finally { Monitor.Exit(m_runningScripts); } } else { logger.Warn("Dialplan engine monitoring thread could not acquire a lock on the running scripts list."); } if (killScripts != null) { for (int index = 0; index < killScripts.Length; index++) { DialPlanExecutingScript killScript = killScripts[index]; DialPlanContext dialPlanContext = killScript.ExecutingDialPlanContext; if (!killScript.Complete) { killScript.LogDelegate(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Long running dialplan script is being forcefully terminated.", killScript.Owner)); } try { if (dialPlanContext != null && !dialPlanContext.IsAnswered) { // The dialplan script has finished but the client call has not been answered. There could have be an // error executing the script or the dialplan could have completed without getting an answer. if (!killScript.ExecutionError.IsNullOrBlank()) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution completed without answering and had an execution error message of " + killScript.ExecutionError + ".", killScript.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.InternalServerError, killScript.ExecutionError, null); } else if (killScript.LastFailureStatus != SIPResponseStatusCodesEnum.None) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution completed without answering and a last failure status of " + killScript.LastFailureStatus + " " + killScript.LastFailureReason + ".", killScript.Owner)); dialPlanContext.CallFailed(killScript.LastFailureStatus, killScript.LastFailureReason, null); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution completed without answering and with no last failure status.", killScript.Owner)); dialPlanContext.CallFailed(SIPResponseStatusCodesEnum.TemporarilyUnavailable, null, null); } } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan execution completed with normal clearing.", killScript.Owner)); } long gcMemory = GC.GetTotalMemory(false); long physicalMemory = System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.AppServer, SIPMonitorEventTypesEnum.DialPlan, "Dial plan finished for " + killScript.Owner + ", gc memory=" + gcMemory + ", physical memory=" + physicalMemory + ", running script count=" + ScriptCount + ".", null)); } catch (Exception finallyExcp) { logger.Error("Exception MonitorScripts Kill. " + finallyExcp.Message); } finally { try { /*if (killScript.DialPlanScriptThread != null && killScript.DialPlanScriptThread.IsAlive) * { * //logger.Debug("Aborting dialplan script thread."); * killScript.DialPlanScriptThread.Abort(); * }*/ killScript.StopExecution(); } catch (ThreadStateException) { } // This exception is thrown when aborting a thread in a suspended state and is expected behaviour. catch (Exception killExcp) { logger.Error("Exception MonitorScripts aborting thread (" + killExcp.GetType().ToString() + "). " + killExcp.Message); } lock (m_runningScripts) { m_runningScripts.Remove(killScript); } logger.Debug("Executing script " + killScript.DialPlanScriptThread.Name + " removed from running scripts list, running script count=" + ScriptCount + "."); } } } Thread.Sleep(500); } if (StopScriptMonitoring) { if (m_runningScripts.Count > 0) { for (int index = 0; index < m_runningScripts.Count; index++) { if (m_runningScripts[index].DialPlanScriptThread != null && m_runningScripts[index].DialPlanScriptThread.IsAlive) { try { m_runningScripts[index].DialPlanScriptThread.Abort(); } catch (Exception finalKill) { logger.Debug("Exception on script final kill. " + finalKill.Message); } } } } } } catch (Exception excp) { logger.Error("Exception MonitorScripts. " + excp); } }