private void ReceiveLoop()
{
try
{
while (true)
{
//check to see if we need to stop
if (mainLoopRunning == false)
{
break;
}
List<AutomationMessage> newMessages = new List<AutomationMessage>();
lock (IncomingQueueLock)
{
while (incoming.Count > 0)
{
newMessages.Add(incoming.Dequeue());
}
}
bool updateJobs = false;
foreach (AutomationMessage m in newMessages)
{
try
{
if (m.Content is JobCreate)
{
//add job
Job j = ((JobCreate)m.Content).j;
JobStatus js = new JobStatus();
if (j.ISOs == null)
{
j.ISOs = new SerializableDictionary<string, string>();
}
if (j.Properties == null)
{
j.Properties = new SerializableDictionary<string, string>();
}
lock (JobsDictLock)
{
jobs[j] = js;
//check required fields
if (String.IsNullOrEmpty(j.Configuration))
{
js.ErrorOut("Configuration cannot be null or empty", null, null);
}
else if (vmMap.ContainsKey(j.Configuration))
{
//set the VM path for visibility to jobmanagerconsole
jobs[j].VMPath = vmMap[j.Configuration].Identifier;
}
}
updateJobs = true;
}
else if (m.Content is SimpleRequest)
{
SimpleRequest srm = (SimpleRequest)m.Content;
if (srm.Request == SimpleRequests.JobRequest)
{
lock (JobsDictLock)
{
bool found = false;
foreach (Job j in jobs.Keys)
{
JobStatus js = jobs[j];
if (js.State == JobStates.VMStarted)
{
VirtualMachine vm = vmMap[j.Configuration];
if (vm.IsSameHost(m.From))
{
AutomationMessage toSend = new AutomationMessage(vm.HostName, m.Id, new JobReturn(j));
SendToHost(toSend);
found = true;
js.State = JobStates.AutoStarted;
break;
}
}
}
if (!found)
{
AutomationMessage toSend = new AutomationMessage(m.From, m.Id, new ErrorMessage(ErrorMessage.ERROR_NO_JOB_FOUND));
SendToHost(toSend);
}
}
}
else if (srm.Request == SimpleRequests.AllVMRequest)
{
try
{
AutomationMessage toSend = new AutomationMessage(m.From, m.Id, new VMRequestReturn(vmHost.AllVMIdentifiers.ToArray(), lockedVMs.ToArray()));
SendToHost(toSend);
}
catch (Exception ex)
{
EventLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
AutomationMessage toSend = new AutomationMessage(m.From, m.Id, new ErrorMessage(ex.ToString()));
SendToHost(toSend);
}
}
else if (srm.Request == SimpleRequests.JobReport)
{
lock (JobsDictLock)
{
AutomationMessage toSend = new AutomationMessage(m.From, m.Id, new JobReportReturn(jobs));
SendToHost(toSend);
}
}
}
else if (m.Content is JobCompleted)
{
JobCompleted jcm = (JobCompleted)m.Content;
lock (JobsDictLock)
{
foreach (Job j in jobs.Keys)
{
if (j.JobID == jcm.Job.JobID)
{
JobStatus js = jobs[j];
js.Result = jcm.Result;
js.State = JobStates.AutoFinished;
updateJobs = true;
}
}
}
}
else if (m.Content is JobCancelCommand)
{
JobCancelCommand jcm = (JobCancelCommand)m.Content;
lock (JobsDictLock)
{
foreach (Job j in jobs.Keys)
{
if (j.JobID == jcm.JobID)
{
JobStatus js = jobs[j];
js.ErrorOut("Job was canceled by user", null, null);
updateJobs = true;
break;
}
}
}
}
else if (m.Content is JobDeleteCommand)
{
JobDeleteCommand jdm = (JobDeleteCommand)m.Content;
lock (JobsDictLock)
{
Job toDelete = null;
foreach (Job j in jobs.Keys)
{
if (j.JobID == jdm.JobID)
{
toDelete = j;
break;
}
}
if (toDelete != null)
{
jobs.Remove(toDelete);
}
}
}
else if (m.Content is LockVMCommand)
{
LockVMCommand cmd = (LockVMCommand)m.Content;
if (!lockedVMs.Contains(cmd.VMPath))
{
lockedVMs.Add(cmd.VMPath);
}
}
else if (m.Content is UnLockVMCommand)
{
UnLockVMCommand cmd = (UnLockVMCommand)m.Content;
if (lockedVMs.Contains(cmd.VMPath))
{
lockedVMs.Remove(cmd.VMPath);
}
}
else
{
EventLog.WriteEntry("Unknown message type " + m.Content.GetType().ToString(), EventLogEntryType.Error);
string badFilePath = Path.Combine(AppConfig.Inbox.FullName, m.Id + ".xml.bad");
File.WriteAllText(badFilePath, m.ToXML(true));
}
}
catch (Exception ex)
{
string badFilePath = Path.Combine(AppConfig.Inbox.FullName, m.Id + ".xml.bad");
EventLog.WriteEntry(string.Format("Exception while processing message. Message saved to \"{0}\". Exception: {1}", badFilePath, ex.ToString()), EventLogEntryType.Error);
File.WriteAllText(badFilePath, m.ToXML(true));
}
}
if (updateJobs)
{
CheckJobs();
}
lock (ExecuteLock)
{
//check for more items
lock (IncomingQueueLock)
{
if (incoming.Count > 0)
{
continue;
}
}
//check to see if we should still be running
if (mainLoopRunning == false)
{
break;
}
Monitor.Wait(ExecuteLock);
}
}
}
catch (ThreadAbortException)
{
//eat it
}
catch (Exception ex)
{
EventLog.WriteEntry("Exception in receive loop: " + ex.ToString());
throw;
}
}