Browse Source

commit progress made so far. does not build yet

master
jvilalta unknown 14 years ago
parent
commit
27f8f2e273
9 changed files with 874 additions and 859 deletions
  1. +3
    -1
      .gitignore
  2. +162
    -160
      ClickForensics.Quartz.Manager/AddJobForm.cs
  3. +38
    -37
      ClickForensics.Quartz.Manager/CronTriggerDisplay.cs
  4. +11
    -10
      ClickForensics.Quartz.Manager/JobNode.cs
  5. +366
    -363
      ClickForensics.Quartz.Manager/MainForm.cs
  6. +5
    -4
      ClickForensics.Quartz.Manager/NativeJobDetailDisplay.cs
  7. +278
    -274
      ClickForensics.Quartz.Manager/QuartzScheduler.cs
  8. +11
    -10
      ClickForensics.Quartz.Manager/TriggerNode.cs
  9. BIN
      lib/Quartz.dll

+ 3
- 1
.gitignore View File

@@ -1,4 +1,6 @@
obj/ obj/
bin/ bin/
*.user *.user
*.suo
*.suo
*.exe
*.msi

+ 162
- 160
ClickForensics.Quartz.Manager/AddJobForm.cs View File

@@ -8,169 +8,171 @@ using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using Quartz; using Quartz;
using System.Reflection; using System.Reflection;
using Quartz.Impl;
using Quartz.Impl.Triggers;
using Quartz.Job; using Quartz.Job;
using System.IO; using System.IO;


namespace ClickForensics.Quartz.Manager namespace ClickForensics.Quartz.Manager
{ {
public partial class AddJobForm : Form
{
public AddJobForm()
{
InitializeComponent();
loadJobAssemblies();
cboTriggerType.Items.Add("Cron");
cboTriggerType.SelectedItem = "Cron";
if (cboJobType.SelectedText == "NativeJob")
{
jobDataListView.Items.Add(new ListViewItem(new string[] { "consumeStreams", "true" }));
jobDataListView.Items.Add(new ListViewItem(new string[] { "waitForProcess", "true" }));
txtKey.Text = "command";
}
}
private void loadJobAssemblies()
{
FileStream stream = File.OpenRead("JobAssemblies.txt");
StreamReader reader = new StreamReader(stream);
string line;
SortedList<string, string> jobTypes = new SortedList<string, string>();
while ((line = reader.ReadLine()) != null)
{
Assembly assembly = Assembly.LoadFile(Environment.CurrentDirectory + "\\" + line);
foreach (Type type in assembly.GetTypes())
{
if (typeof(IJob).IsAssignableFrom(type) && type.IsClass)
{
jobTypes.Add(type.FullName, assembly.GetName().Name);
}
}
}
foreach (var item in jobTypes)
{
cboJobType.Items.Add(new JobType() { AssemblyName = item.Value, FullName = item.Key });
}
//cboJobType.Items.AddRange(jobTypes.Values.ToArray<string>());
}
public AddJobForm(TriggerNode node)
: this()
{
setTriggerData((CronTrigger)node.Trigger);
setJobData(((JobNode)node.Parent.Parent).Detail);
}
private void setTriggerData(CronTrigger trigger)
{
setTriggerType();
txtCronExpression.Text = trigger.CronExpressionString;
txtTriggerDescription.Text = trigger.Description;
txtTriggerGroup.Text = trigger.Group;
txtTriggerName.Text = trigger.Name;
}
private void setJobData(JobDetail detail)
{
setJobType(detail);
txtJobDescription.Text = detail.Description;
txtJobGroup.Text = detail.Group;
txtJobName.Text = detail.Name;
setJobDataMap(detail);
}
private void setJobDataMap(JobDetail detail)
{
jobDataListView.Items.Clear();
foreach (var item in detail.JobDataMap.GetKeys())
{
jobDataListView.Items.Add(new ListViewItem(new string[] { item, detail.JobDataMap.Get(item).ToString() }));
}
}
private void setJobType(JobDetail detail)
{
cboJobType.SelectedItem = detail.JobType.FullName;
}
private void setTriggerType()
{
//nothing to do right now
}
public JobDetail JobDetail { get; set; }
public Trigger Trigger { get; set; }
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnAdd_Click(object sender, EventArgs e)
{
JobDetail = getJobDetail();
Trigger = getTrigger();
Trigger.JobGroup = JobDetail.Group;
Trigger.JobName = JobDetail.Name;
this.Close();
}
private JobDetail getJobDetail()
{
JobDetail detail = new JobDetail();
detail.Description = txtJobDescription.Text;
detail.Group = txtJobGroup.Text;
detail.JobDataMap = getJobDataMap();
detail.JobType = getJobType();
detail.Name = txtJobName.Text;
return detail;
}
private Trigger getTrigger()
{
Trigger trigger;
if (cboTriggerType.SelectedText == "Simple")
{
trigger = new SimpleTrigger();
}
else
{
trigger = new CronTrigger();
((CronTrigger)trigger).CronExpressionString = txtCronExpression.Text;
}
trigger.Description = txtTriggerDescription.Text;
trigger.Group = txtTriggerGroup.Text;
trigger.Name = txtTriggerName.Text;
return trigger;
}
private Type getJobType()
{
JobType type = (JobType)cboJobType.SelectedItem;
return Type.GetType(type.FullName + "," + type.AssemblyName, true);
}
private JobDataMap getJobDataMap()
{
JobDataMap map = new JobDataMap();
foreach (ListViewItem item in jobDataListView.Items)
{
map.Add(item.SubItems[0].Text, item.SubItems[1].Text);
}
return map;
}
private void btnAddKeyValue_Click(object sender, EventArgs e)
{
ListViewItem item = new ListViewItem(new string[] { txtKey.Text, txtValue.Text });
jobDataListView.Items.Add(item);
}
private void btnDelete_Click(object sender, EventArgs e)
{
foreach (ListViewItem item in jobDataListView.SelectedItems)
{
jobDataListView.Items.Remove(item);
}
}
}
public partial class AddJobForm : Form
{
public AddJobForm()
{
InitializeComponent();
loadJobAssemblies();
cboTriggerType.Items.Add("Cron");
cboTriggerType.SelectedItem = "Cron";
if (cboJobType.SelectedText == "NativeJob")
{
jobDataListView.Items.Add(new ListViewItem(new string[] { "consumeStreams", "true" }));
jobDataListView.Items.Add(new ListViewItem(new string[] { "waitForProcess", "true" }));
txtKey.Text = "command";
}
}
private void loadJobAssemblies()
{
FileStream stream = File.OpenRead("JobAssemblies.txt");
StreamReader reader = new StreamReader(stream);
string line;
SortedList<string, string> jobTypes = new SortedList<string, string>();
while ((line = reader.ReadLine()) != null)
{
Assembly assembly = Assembly.LoadFile(Environment.CurrentDirectory + "\\" + line);
foreach (Type type in assembly.GetTypes())
{
if (typeof(IJob).IsAssignableFrom(type) && type.IsClass)
{
jobTypes.Add(type.FullName, assembly.GetName().Name);
}
}
}
foreach (var item in jobTypes)
{
cboJobType.Items.Add(new JobType() { AssemblyName = item.Value, FullName = item.Key });
}
//cboJobType.Items.AddRange(jobTypes.Values.ToArray<string>());
}
public AddJobForm(TriggerNode node)
: this()
{
setTriggerData((CronTriggerImpl)node.Trigger);
setJobData(((JobNode)node.Parent.Parent).Detail);
}
private void setTriggerData(CronTriggerImpl trigger)
{
setTriggerType();
txtCronExpression.Text = trigger.CronExpressionString;
txtTriggerDescription.Text = trigger.Description;
txtTriggerGroup.Text = trigger.Name.Group;
txtTriggerName.Text = trigger.Name;
}
private void setJobData(IJobDetail detail)
{
setJobType(detail);
txtJobDescription.Text = detail.Description;
txtJobGroup.Text = detail.Key.Group;
txtJobName.Text = detail.Key.Name;
setJobDataMap(detail);
}
private void setJobDataMap(IJobDetail detail)
{
jobDataListView.Items.Clear();
foreach (var item in detail.JobDataMap.GetKeys())
{
jobDataListView.Items.Add(new ListViewItem(new string[] { item, detail.JobDataMap.Get(item).ToString() }));
}
}
private void setJobType(IJobDetail detail)
{
cboJobType.SelectedItem = detail.JobType.FullName;
}
private void setTriggerType()
{
//nothing to do right now
}
public IJobDetail JobDetail { get; set; }
public AbstractTrigger Trigger { get; set; }
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnAdd_Click(object sender, EventArgs e)
{
JobDetail = getJobDetail();
AbstractTrigger trigger = getTrigger();
Trigger.JobGroup = JobDetail.Key.Group;
Trigger.JobName = JobDetail.Key.Name;
this.Close();
}
private IJobDetail getJobDetail()
{
IJobDetail detail = new IJobDetail();
detail.Description = txtJobDescription.Text;
detail.Group = txtJobGroup.Text;
detail.JobDataMap = getJobDataMap();
detail.JobType = getJobType();
detail.Name = txtJobName.Text;
return detail;
}
private AbstractTrigger getTrigger()
{
AbstractTrigger trigger;
if (cboTriggerType.SelectedText == "Simple")
{
trigger = new SimpleTrigger();
}
else
{
trigger = new CronTrigger();
((CronTrigger)trigger).CronExpressionString = txtCronExpression.Text;
}
trigger.Description = txtTriggerDescription.Text;
trigger.Group = txtTriggerGroup.Text;
trigger.Name = txtTriggerName.Text;
return trigger;
}
private Type getJobType()
{
JobType type = (JobType)cboJobType.SelectedItem;
return Type.GetType(type.FullName + "," + type.AssemblyName, true);
}
private JobDataMap getJobDataMap()
{
JobDataMap map = new JobDataMap();
foreach (ListViewItem item in jobDataListView.Items)
{
map.Add(item.SubItems[0].Text, item.SubItems[1].Text);
}
return map;
}
private void btnAddKeyValue_Click(object sender, EventArgs e)
{
ListViewItem item = new ListViewItem(new string[] { txtKey.Text, txtValue.Text });
jobDataListView.Items.Add(item);
}
private void btnDelete_Click(object sender, EventArgs e)
{
foreach (ListViewItem item in jobDataListView.SelectedItems)
{
jobDataListView.Items.Remove(item);
}
}
}
} }

+ 38
- 37
ClickForensics.Quartz.Manager/CronTriggerDisplay.cs View File

@@ -7,48 +7,49 @@ using System.Linq;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using Quartz; using Quartz;
using Quartz.Impl.Triggers;


namespace ClickForensics.Quartz.Manager namespace ClickForensics.Quartz.Manager
{ {
public partial class CronTriggerDisplay : UserControl
{
public CronTriggerDisplay()
{
InitializeComponent();
this.Load += new EventHandler(CronTriggerDisplay_Load);
}
public partial class CronTriggerDisplay : UserControl
{
public CronTriggerDisplay()
{
InitializeComponent();
this.Load += new EventHandler(CronTriggerDisplay_Load);
}


void CronTriggerDisplay_Load(object sender, EventArgs e)
{
txtCronExpression.Text = _trigger.CronExpressionString;
lblDescription.Text = _trigger.Description;
lblGroup.Text = _trigger.Group;
lblName.Text = _trigger.Name;
if (_trigger.GetNextFireTimeUtc().HasValue)
{
lblNextFireTime.Text = _trigger.GetNextFireTimeUtc().Value.ToLocalTime().ToString();
}
else
{
lblNextFireTime.Text = "Unknown";
}
void CronTriggerDisplay_Load(object sender, EventArgs e)
{
txtCronExpression.Text = _trigger.CronExpressionString;
lblDescription.Text = _trigger.Description;
lblGroup.Text = _trigger.Group;
lblName.Text = _trigger.Name;
if (_trigger.GetNextFireTimeUtc().HasValue)
{
lblNextFireTime.Text = _trigger.GetNextFireTimeUtc().Value.ToLocalTime().ToString();
}
else
{
lblNextFireTime.Text = "Unknown";
}


if (_trigger.GetPreviousFireTimeUtc().HasValue)
{
lblPreviousFireTime.Text = _trigger.GetPreviousFireTimeUtc().Value.ToLocalTime().ToString();
}
else
{
lblPreviousFireTime.Text = "Unknown";
}
}
public CronTriggerDisplay(CronTrigger trigger)
: this()
{
_trigger = trigger;
if (_trigger.GetPreviousFireTimeUtc().HasValue)
{
lblPreviousFireTime.Text = _trigger.GetPreviousFireTimeUtc().Value.ToLocalTime().ToString();
}
else
{
lblPreviousFireTime.Text = "Unknown";
}
}
public CronTriggerDisplay(CronTriggerImpl trigger)
: this()
{
_trigger = trigger;


}
}


private CronTrigger _trigger;
}
private CronTriggerImpl _trigger;
}
} }

+ 11
- 10
ClickForensics.Quartz.Manager/JobNode.cs View File

@@ -4,18 +4,19 @@ using System.Linq;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using Quartz; using Quartz;
using Quartz.Impl;


namespace ClickForensics.Quartz.Manager namespace ClickForensics.Quartz.Manager
{ {
public class JobNode : TreeNode
{
public JobNode(JobDetail jobDetail)
: base()
{
this.Text = jobDetail.Name;
Detail = jobDetail;
}
public JobDetail Detail { get; private set; }
public class JobNode : TreeNode
{
public JobNode(IJobDetail jobDetail)
: base()
{
this.Text = jobDetail.Key.Name;
Detail = jobDetail;
}
public IJobDetail Detail { get; private set; }


}
}
} }

+ 366
- 363
ClickForensics.Quartz.Manager/MainForm.cs View File

@@ -11,370 +11,373 @@ using Quartz.Collection;
using System.Net.Sockets; using System.Net.Sockets;
//using ClickForensics.Quartz.Jobs; //using ClickForensics.Quartz.Jobs;
using System.IO; using System.IO;
using Quartz.Impl;
using Quartz.Impl.Triggers;


namespace ClickForensics.Quartz.Manager namespace ClickForensics.Quartz.Manager
{ {
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
jobGroupsTreeView.AfterSelect += new TreeViewEventHandler(jobGroupsTreeView_AfterSelect);
ctxScheduler.Opening += new CancelEventHandler(ctxScheduler_Opening);
jobGroupsTreeView.MouseDown += new MouseEventHandler(jobGroupsTreeView_MouseDown);

}

void ctxScheduler_Opening(object sender, CancelEventArgs e)
{

}

void jobGroupsTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
jobDetailsToggle(false);
if (e.Node is TriggerNode || e.Node is JobNode)
{
btnDeleteJob.Enabled = true;
}
else
{
btnDeleteJob.Enabled = false;
}

if (e.Node is JobNode)
{
btnRunJobNow.Enabled = true;
pnlDetails.Controls.Add(new NativeJobDetailDisplay(((JobNode)e.Node).Detail));
jobDetailsToggle(true);
}
else
{
btnRunJobNow.Enabled = false;

}
if (e.Node is TriggerNode)
{
btnPause.Enabled = true;
setPauseButtonText();
if (((TriggerNode)e.Node).Trigger is CronTrigger)
{
pnlDetails.Controls.Add(new CronTriggerDisplay((CronTrigger)((TriggerNode)e.Node).Trigger));
jobDetailsToggle(true);
}
btnEdit.Enabled = true;
}
else
{
btnEdit.Enabled = false;
btnPause.Enabled = false;
}
}

private void setPauseButtonText()
{
TriggerNode node = (TriggerNode)jobGroupsTreeView.SelectedNode;
string name = node.Trigger.Name;
string group = node.Trigger.Group;
if (Scheduler.GetScheduler().GetTriggerState(name, group) == TriggerState.Paused)
{
btnPause.Text = "Resume";
}
else
{
btnPause.Text = "Pause";
}
}

private void connectToolStripMenuItem_Click(object sender, EventArgs e)
{
using (ServerConnectForm form = new ServerConnectForm())
{
form.ShowDialog();
try
{
Scheduler = new QuartzScheduler(form.Server, form.Port, form.Scheduler);
serverConnectStatusLabel.Text = string.Format("Connected to {0}", Scheduler.Address);
connectToolStripMenuItem.Enabled = false;
jobsToolStripMenuItem.Enabled = true;
loadJobGroups();
updateRunningJobs();
}
catch (SocketException ex)
{
ErrorDialog dialog = new ErrorDialog();
dialog.Message = string.Format("Unable to connect to scheduler {0} on {1}:{2}", form.Scheduler, form.Server, form.Port);
dialog.Description = ex.Message;
dialog.ShowDialog();
}
form.Close();
}
//loadGlobalTriggers();
}

//private void loadGlobalTriggers()
//{
// foreach (IJobListener jobListener in Scheduler.GetScheduler().GetJobDetail(null,null)..GlobalJobListeners)
// {
// globalTriggersListView.Items.Add(jobListener.Name);
// }
//}

private void loadJobGroups()
{

try
{
this.Cursor = Cursors.WaitCursor;

jobDetailsToggle(false);
jobGroupsTreeView.Nodes.Clear();
SchedulerNode schedulerNode = new SchedulerNode(Scheduler);
schedulerNode.ContextMenuStrip = ctxScheduler;
jobGroupsTreeView.Nodes.Add(schedulerNode);
TreeNode jobGroupsNode = schedulerNode.Nodes.Add("Job Groups");
string[] jobGroups = Scheduler.GetScheduler().JobGroupNames;
foreach (string jobGroup in jobGroups)
{
TreeNode jobGroupNode = jobGroupsNode.Nodes.Add(jobGroup);
TreeNode jobsNode = jobGroupNode.Nodes.Add("Jobs");
addJobNodes(jobsNode);
}

jobGroupsTreeView.Nodes[0].Expand();
jobGroupsNode.Expand();

StripStatusLabel_Job_Groups.Text = DateTime.Now.ToString("yyyy.MM.dd HH:mm.ss");

}
finally
{
this.Cursor = Cursors.Default;
}


}

private void jobDetailsToggle(bool isVisible)
{
if (isVisible == false)
{
pnlDetails.Controls.Clear();
}
}

void jobGroupsTreeView_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
TreeNode node = jobGroupsTreeView.GetNodeAt(e.X, e.Y);
if (node != null)
{
jobGroupsTreeView.SelectedNode = node;
ctxScheduler.Show(jobGroupsTreeView, e.Location);
}
}
}
//private void loadJobs()
//{
// foreach (TreeNode node in jobGroupsTreeView.Nodes)
// {
// addJobNodes(node);
// }
//}

private void addJobNodes(TreeNode node)
{
string group = node.Parent.Text;
string[] jobs = Scheduler.GetScheduler().GetJobNames(group);
foreach (string jobName in jobs)
{
try
{
JobDetail detail = Scheduler.GetScheduler().GetJobDetail(jobName, group);
JobNode jobNode = new JobNode(detail);
node.Nodes.Add(jobNode);
addTriggerNodes(jobNode);
addListenerNodes(jobNode);
}
catch (Exception ex)
{
//TODO: Do something useful with this exception. Most likely cause is the client does not have a copy of a given dll and can't load the type.
}
}
}

private void addListenerNodes(JobNode node)
{
string jobName = node.Text;
string jobGroupName = node.Parent.Text;
string[] listenerNames = node.Detail.JobListenerNames;
foreach (string listener in listenerNames)
{
node.Text = string.Format("JL {0}", listenerNames);
}
//ISet set = Scheduler.GetScheduler().JobListenerNames;
}

private void addTriggerNodes(TreeNode treeNode)
{
Trigger[] triggers = Scheduler.GetScheduler().GetTriggersOfJob(treeNode.Text, treeNode.Parent.Parent.Text);
TreeNode triggersNode = treeNode.Nodes.Add("Triggers");
foreach (Trigger trigger in triggers)
{
TriggerNode node = new TriggerNode(trigger);
triggersNode.Nodes.Add(node);
}

}
private void updateRunningJobs()
{
try
{
this.Cursor = Cursors.WaitCursor;

timer_Refresh_Running_Jobs.Stop();

listView_RunningJobs.Items.Clear();

DataTable table = Scheduler.GetRunningJobs();
foreach (DataRow row in table.Rows)
{
//JobName JobDuration
ListViewItem item = new ListViewItem(new string[] { Convert.ToString(row["JobName"]), Convert.ToString(row["Runtime"]) });
listView_RunningJobs.Items.Add(item);
}
StripStatusLabel_Jobs_Refresh_date.Text = DateTime.Now.ToString("yyyy.MM.dd HH:mm.ss");


//reset the timer ( documentation not clear if .stop = restart @ 0 in timing, but changing the interval sure should do that. )
int timer_was = timer_Refresh_Running_Jobs.Interval;
timer_Refresh_Running_Jobs.Interval = timer_was + 1;
timer_Refresh_Running_Jobs.Interval = timer_was;

timer_Refresh_Running_Jobs.Start();
}
finally
{
this.Cursor = Cursors.Default;
}
}
public QuartzScheduler Scheduler { get; set; }

private void addGlobalListenerToolStripMenuItem_Click(object sender, EventArgs e)
{
AddListenerForm form = new AddListenerForm();
form.ListenerInterface = typeof(IJobListener);
form.ShowDialog();
JobDataMap map = new JobDataMap();
map.Add("type", form.ListenerType);
//Scheduler.ScheduleOneTimeJob(typeof(AddJobListenerJob), map, 0);
loadJobGroups();
}

private void addJobListenerToolStripMenuItem_Click(object sender, EventArgs e)
{
TreeNode selectedNode = jobGroupsTreeView.SelectedNode;
if (selectedNode != null && selectedNode is JobNode)
{
AddListenerForm form = new AddListenerForm();
form.ListenerInterface = typeof(IJobListener);
form.ShowDialog();
//JobHistoryListener listener = new JobHistoryListener();
//listener.Name = null;
//((JobNode)selectedNode).Detail.AddJobListener();
}
}

private void addJobToolStripMenuItem_Click(object sender, EventArgs e)
{
AddJobForm form = new AddJobForm();
form.ShowDialog();
if (form.JobDetail != null && form.Trigger != null)
{
Scheduler.GetScheduler().ScheduleJob(form.JobDetail, form.Trigger);
loadJobGroups();
}
}

private void btnRefreshRunningJobs_Click(object sender, EventArgs e)
{
updateRunningJobs();
}

private void btnRefreshJobGroups_Click(object sender, EventArgs e)
{
loadJobGroups();
}

private void btnRunJobNow_Click(object sender, EventArgs e)
{
JobNode node = (JobNode)jobGroupsTreeView.SelectedNode;
string job = node.Detail.Name;
string group = node.Detail.Group;
Scheduler.GetScheduler().TriggerJobWithVolatileTrigger(job, group);
}

private void btnDeleteJob_Click(object sender, EventArgs e)
{
TreeNode selectedNode = jobGroupsTreeView.SelectedNode;
if (selectedNode is JobNode)
{
JobNode node = (JobNode)jobGroupsTreeView.SelectedNode;
string job = node.Detail.Name;
string group = node.Detail.Group;
Scheduler.GetScheduler().DeleteJob(job, group);
jobGroupsTreeView.SelectedNode.Remove();

}
if (selectedNode is TriggerNode)
{
Scheduler.GetScheduler().UnscheduleJob(((TriggerNode)selectedNode).Trigger.Name, ((TriggerNode)selectedNode).Trigger.Group);
}

//loadJobGroups();
}

private void btnPause_Click(object sender, EventArgs e)
{
TriggerNode node = (TriggerNode)jobGroupsTreeView.SelectedNode;
string name = node.Trigger.Name;
string group = node.Trigger.Group;
if (Scheduler.GetScheduler().GetTriggerState(name, group) == TriggerState.Paused)
{
Scheduler.GetScheduler().ResumeTrigger(name, group);
}
else
{
Scheduler.GetScheduler().PauseTrigger(name, group);
}
setPauseButtonText();
}

private void btnEdit_Click(object sender, EventArgs e)
{
TriggerNode node = (TriggerNode)jobGroupsTreeView.SelectedNode;
AddJobForm form = new AddJobForm(node);
form.ShowDialog();
if (form.JobDetail != null && form.Trigger != null)
{
Scheduler.GetScheduler().RescheduleJob(node.Trigger.Name, node.Trigger.Group, form.Trigger);
loadJobGroups();
}
}

private void backupToolStripMenuItem_Click(object sender, EventArgs e)
{
QuartzScheduler scheduler = ((SchedulerNode)((TreeView)((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl).SelectedNode).Scheduler;
FileDialog dialog = new SaveFileDialog();
dialog.ShowDialog();
FileInfo file = new FileInfo(dialog.FileName);
scheduler.BackupToFile(file);
}

private void timer_Refresh_Running_Jobs_Tick(object sender, EventArgs e)
{
updateRunningJobs();
}
}
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
jobGroupsTreeView.AfterSelect += new TreeViewEventHandler(jobGroupsTreeView_AfterSelect);
ctxScheduler.Opening += new CancelEventHandler(ctxScheduler_Opening);
jobGroupsTreeView.MouseDown += new MouseEventHandler(jobGroupsTreeView_MouseDown);

}

void ctxScheduler_Opening(object sender, CancelEventArgs e)
{

}

void jobGroupsTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
jobDetailsToggle(false);
if (e.Node is TriggerNode || e.Node is JobNode)
{
btnDeleteJob.Enabled = true;
}
else
{
btnDeleteJob.Enabled = false;
}

if (e.Node is JobNode)
{
btnRunJobNow.Enabled = true;
pnlDetails.Controls.Add(new NativeJobDetailDisplay(((JobNode)e.Node).Detail));
jobDetailsToggle(true);
}
else
{
btnRunJobNow.Enabled = false;

}
if (e.Node is TriggerNode)
{
btnPause.Enabled = true;
setPauseButtonText();
if (((TriggerNode)e.Node).Trigger is CronTrigger)
{
pnlDetails.Controls.Add(new CronTriggerDisplay((CronTrigger)((TriggerNode)e.Node).Trigger));
jobDetailsToggle(true);
}
btnEdit.Enabled = true;
}
else
{
btnEdit.Enabled = false;
btnPause.Enabled = false;
}
}

private void setPauseButtonText()
{
TriggerNode node = (TriggerNode)jobGroupsTreeView.SelectedNode;
string name = node.Trigger.Name;
string group = node.Trigger.Group;
if (Scheduler.GetScheduler().GetTriggerState(name, group) == TriggerState.Paused)
{
btnPause.Text = "Resume";
}
else
{
btnPause.Text = "Pause";
}
}

private void connectToolStripMenuItem_Click(object sender, EventArgs e)
{
using (ServerConnectForm form = new ServerConnectForm())
{
form.ShowDialog();
try
{
Scheduler = new QuartzScheduler(form.Server, form.Port, form.Scheduler);
serverConnectStatusLabel.Text = string.Format("Connected to {0}", Scheduler.Address);
connectToolStripMenuItem.Enabled = false;
jobsToolStripMenuItem.Enabled = true;
loadJobGroups();
updateRunningJobs();
}
catch (SocketException ex)
{
ErrorDialog dialog = new ErrorDialog();
dialog.Message = string.Format("Unable to connect to scheduler {0} on {1}:{2}", form.Scheduler, form.Server, form.Port);
dialog.Description = ex.Message;
dialog.ShowDialog();
}
form.Close();
}
//loadGlobalTriggers();
}

//private void loadGlobalTriggers()
//{
// foreach (IJobListener jobListener in Scheduler.GetScheduler().GetJobDetail(null,null)..GlobalJobListeners)
// {
// globalTriggersListView.Items.Add(jobListener.Name);
// }
//}

private void loadJobGroups()
{

try
{
this.Cursor = Cursors.WaitCursor;

jobDetailsToggle(false);
jobGroupsTreeView.Nodes.Clear();
SchedulerNode schedulerNode = new SchedulerNode(Scheduler);
schedulerNode.ContextMenuStrip = ctxScheduler;
jobGroupsTreeView.Nodes.Add(schedulerNode);
TreeNode jobGroupsNode = schedulerNode.Nodes.Add("Job Groups");
string[] jobGroups = Scheduler.GetScheduler().JobGroupNames;
foreach (string jobGroup in jobGroups)
{
TreeNode jobGroupNode = jobGroupsNode.Nodes.Add(jobGroup);
TreeNode jobsNode = jobGroupNode.Nodes.Add("Jobs");
addJobNodes(jobsNode);
}

jobGroupsTreeView.Nodes[0].Expand();
jobGroupsNode.Expand();

StripStatusLabel_Job_Groups.Text = DateTime.Now.ToString("yyyy.MM.dd HH:mm.ss");

}
finally
{
this.Cursor = Cursors.Default;
}


}

private void jobDetailsToggle(bool isVisible)
{
if (isVisible == false)
{
pnlDetails.Controls.Clear();
}
}

void jobGroupsTreeView_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
TreeNode node = jobGroupsTreeView.GetNodeAt(e.X, e.Y);
if (node != null)
{
jobGroupsTreeView.SelectedNode = node;
ctxScheduler.Show(jobGroupsTreeView, e.Location);
}
}
}
//private void loadJobs()
//{
// foreach (TreeNode node in jobGroupsTreeView.Nodes)
// {
// addJobNodes(node);
// }
//}

private void addJobNodes(TreeNode node)
{
string group = node.Parent.Text;
string[] jobs = Scheduler.GetScheduler().GetJobNames(group);
foreach (string jobName in jobs)
{
try
{
IJobDetail detail = Scheduler.GetScheduler().GetJobDetail(new JobKey(jobName, group));
JobNode jobNode = new JobNode(detail);
node.Nodes.Add(jobNode);
addTriggerNodes(jobNode);
addListenerNodes(jobNode);
}
catch (Exception ex)
{
//TODO: Do something useful with this exception. Most likely cause is the client does not have a copy of a given dll and can't load the type.
}
}
}

private void addListenerNodes(JobNode node)
{
string jobName = node.Text;
string jobGroupName = node.Parent.Text;
//TODO: see joblistenermanager get listeners
//string[] listenerNames = node.Detail.JobListenerNames;
//foreach (string listener in listenerNames)
//{
// node.Text = string.Format("JL {0}", listenerNames);
//}
//ISet set = Scheduler.GetScheduler().JobListenerNames;
}

private void addTriggerNodes(TreeNode treeNode)
{
AbstractTrigger[] triggers = Scheduler.GetScheduler().GetTriggersOfJob(treeNode.Text, treeNode.Parent.Parent.Text);
TreeNode triggersNode = treeNode.Nodes.Add("Triggers");
foreach (AbstractTrigger trigger in triggers)
{
TriggerNode node = new TriggerNode(trigger);
triggersNode.Nodes.Add(node);
}

}
private void updateRunningJobs()
{
try
{
this.Cursor = Cursors.WaitCursor;

timer_Refresh_Running_Jobs.Stop();

listView_RunningJobs.Items.Clear();

DataTable table = Scheduler.GetRunningJobs();
foreach (DataRow row in table.Rows)
{
//JobName JobDuration
ListViewItem item = new ListViewItem(new string[] { Convert.ToString(row["JobName"]), Convert.ToString(row["Runtime"]) });
listView_RunningJobs.Items.Add(item);
}
StripStatusLabel_Jobs_Refresh_date.Text = DateTime.Now.ToString("yyyy.MM.dd HH:mm.ss");


//reset the timer ( documentation not clear if .stop = restart @ 0 in timing, but changing the interval sure should do that. )
int timer_was = timer_Refresh_Running_Jobs.Interval;
timer_Refresh_Running_Jobs.Interval = timer_was + 1;
timer_Refresh_Running_Jobs.Interval = timer_was;

timer_Refresh_Running_Jobs.Start();
}
finally
{
this.Cursor = Cursors.Default;
}
}
public QuartzScheduler Scheduler { get; set; }

private void addGlobalListenerToolStripMenuItem_Click(object sender, EventArgs e)
{
AddListenerForm form = new AddListenerForm();
form.ListenerInterface = typeof(IJobListener);
form.ShowDialog();
JobDataMap map = new JobDataMap();
map.Add("type", form.ListenerType);
//Scheduler.ScheduleOneTimeJob(typeof(AddJobListenerJob), map, 0);
loadJobGroups();
}

private void addJobListenerToolStripMenuItem_Click(object sender, EventArgs e)
{
TreeNode selectedNode = jobGroupsTreeView.SelectedNode;
if (selectedNode != null && selectedNode is JobNode)
{
AddListenerForm form = new AddListenerForm();
form.ListenerInterface = typeof(IJobListener);
form.ShowDialog();
//JobHistoryListener listener = new JobHistoryListener();
//listener.Name = null;
//((JobNode)selectedNode).Detail.AddJobListener();
}
}

private void addJobToolStripMenuItem_Click(object sender, EventArgs e)
{
AddJobForm form = new AddJobForm();
form.ShowDialog();
if (form.JobDetail != null && form.Trigger != null)
{
Scheduler.GetScheduler().ScheduleJob(form.JobDetail, form.Trigger);
loadJobGroups();
}
}

private void btnRefreshRunningJobs_Click(object sender, EventArgs e)
{
updateRunningJobs();
}

private void btnRefreshJobGroups_Click(object sender, EventArgs e)
{
loadJobGroups();
}

private void btnRunJobNow_Click(object sender, EventArgs e)
{
JobNode node = (JobNode)jobGroupsTreeView.SelectedNode;
string job = node.Detail.Name;
string group = node.Detail.Group;
Scheduler.GetScheduler().TriggerJobWithVolatileTrigger(job, group);
}

private void btnDeleteJob_Click(object sender, EventArgs e)
{
TreeNode selectedNode = jobGroupsTreeView.SelectedNode;
if (selectedNode is JobNode)
{
JobNode node = (JobNode)jobGroupsTreeView.SelectedNode;
string job = node.Detail.Name;
string group = node.Detail.Group;
Scheduler.GetScheduler().DeleteJob(job, group);
jobGroupsTreeView.SelectedNode.Remove();

}
if (selectedNode is TriggerNode)
{
Scheduler.GetScheduler().UnscheduleJob(((TriggerNode)selectedNode).Trigger.Name, ((TriggerNode)selectedNode).Trigger.Group);
}

//loadJobGroups();
}

private void btnPause_Click(object sender, EventArgs e)
{
TriggerNode node = (TriggerNode)jobGroupsTreeView.SelectedNode;
string name = node.Trigger.Name;
string group = node.Trigger.Group;
if (Scheduler.GetScheduler().GetTriggerState(name, group) == TriggerState.Paused)
{
Scheduler.GetScheduler().ResumeTrigger(name, group);
}
else
{
Scheduler.GetScheduler().PauseTrigger(name, group);
}
setPauseButtonText();
}

private void btnEdit_Click(object sender, EventArgs e)
{
TriggerNode node = (TriggerNode)jobGroupsTreeView.SelectedNode;
AddJobForm form = new AddJobForm(node);
form.ShowDialog();
if (form.JobDetail != null && form.Trigger != null)
{
Scheduler.GetScheduler().RescheduleJob(node.Trigger.Name, node.Trigger.Group, form.Trigger);
loadJobGroups();
}
}

private void backupToolStripMenuItem_Click(object sender, EventArgs e)
{
QuartzScheduler scheduler = ((SchedulerNode)((TreeView)((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl).SelectedNode).Scheduler;
FileDialog dialog = new SaveFileDialog();
dialog.ShowDialog();
FileInfo file = new FileInfo(dialog.FileName);
scheduler.BackupToFile(file);
}

private void timer_Refresh_Running_Jobs_Tick(object sender, EventArgs e)
{
updateRunningJobs();
}
}
} }

+ 5
- 4
ClickForensics.Quartz.Manager/NativeJobDetailDisplay.cs View File

@@ -7,6 +7,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using Quartz; using Quartz;
using Quartz.Impl;


namespace ClickForensics.Quartz.Manager namespace ClickForensics.Quartz.Manager
{ {
@@ -21,8 +22,8 @@ namespace ClickForensics.Quartz.Manager
void NativeJobDetailDisplay_Load(object sender, EventArgs e) void NativeJobDetailDisplay_Load(object sender, EventArgs e)
{ {
lblDescription.Text = _detail.Description; lblDescription.Text = _detail.Description;
lblGroup.Text = _detail.Group;
lblName.Text = _detail.Name;
lblGroup.Text = _detail.Key.Group;
lblName.Text = _detail.Key.Name;
loadJobDataMap(); loadJobDataMap();
} }


@@ -33,12 +34,12 @@ namespace ClickForensics.Quartz.Manager
jobDataListView.Items.Add(new ListViewItem(new string[] { item, _detail.JobDataMap.Get(item).ToString() })); jobDataListView.Items.Add(new ListViewItem(new string[] { item, _detail.JobDataMap.Get(item).ToString() }));
} }
} }
public NativeJobDetailDisplay(JobDetail detail)
public NativeJobDetailDisplay(IJobDetail detail)
: this() : this()
{ {
_detail = detail; _detail = detail;
} }
private JobDetail _detail;
private IJobDetail _detail;


} }
} }

+ 278
- 274
ClickForensics.Quartz.Manager/QuartzScheduler.cs View File

@@ -11,301 +11,305 @@ using System.Collections;
using System.Windows.Forms; using System.Windows.Forms;
using System.IO; using System.IO;
using System.Xml.Linq; using System.Xml.Linq;
using Quartz.Impl.Matchers;
using Quartz.Impl.Triggers;
using Quartz.Util;


namespace ClickForensics.Quartz.Manager namespace ClickForensics.Quartz.Manager
{ {
public class QuartzScheduler
{
public QuartzScheduler(string server, int port, string scheduler)
{
Address = string.Format("tcp://{0}:{1}/{2}", server, port, scheduler);
_schedulerFactory = new StdSchedulerFactory(getProperties(Address));
public class QuartzScheduler
{
public QuartzScheduler(string server, int port, string scheduler)
{
Address = string.Format("tcp://{0}:{1}/{2}", server, port, scheduler);
_schedulerFactory = new StdSchedulerFactory(getProperties(Address));


try
{
_scheduler = _schedulerFactory.GetScheduler();
}
catch (SchedulerException se)
{
MessageBox.Show("Unable to connect to the specified server", "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
public string Address { get; private set; }
private NameValueCollection getProperties(string address)
{
NameValueCollection properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "RemoteClient";
properties["quartz.scheduler.proxy"] = "true";
properties["quartz.threadPool.threadCount"] = "0";
properties["quartz.scheduler.proxy.address"] = address;
return properties;
}
public IScheduler GetScheduler()
{
return _scheduler;
}
public DataTable GetJobs()
{
DataTable table = new DataTable();
table.Columns.Add("GroupName");
table.Columns.Add("JobName");
table.Columns.Add("JobDescription");
table.Columns.Add("TriggerName");
table.Columns.Add("TriggerGroupName");
table.Columns.Add("TriggerType");
table.Columns.Add("TriggerState");
table.Columns.Add("NextFireTime");
table.Columns.Add("PreviousFireTime");
string[] jobGroups = GetScheduler().JobGroupNames;
foreach (string group in jobGroups)
{
string[] jobNames = GetScheduler().GetJobNames(group);
foreach (string job in jobNames)
{
JobDetail detail = GetScheduler().GetJobDetail(job, group);
Trigger[] triggers = GetScheduler().GetTriggersOfJob(job, group);
foreach (Trigger trigger in triggers)
{
DataRow row = table.NewRow();
row["GroupName"] = group;
row["JobName"] = job;
row["JobDescription"] = detail.Description;
row["TriggerName"] = trigger.Name;
row["TriggerGroupName"] = trigger.Group;
row["TriggerType"] = trigger.GetType().Name;
row["TriggerState"] = GetScheduler().GetTriggerState(trigger.Name, trigger.Group);
DateTime? nextFireTime = trigger.GetNextFireTimeUtc();
if (nextFireTime != null)
{
row["NextFireTime"] = TimeZone.CurrentTimeZone.ToLocalTime((DateTime)nextFireTime);
}
try
{
_scheduler = _schedulerFactory.GetScheduler();
}
catch (SchedulerException se)
{
MessageBox.Show("Unable to connect to the specified server", "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
public string Address { get; private set; }
private NameValueCollection getProperties(string address)
{
NameValueCollection properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "RemoteClient";
properties["quartz.scheduler.proxy"] = "true";
properties["quartz.threadPool.threadCount"] = "0";
properties["quartz.scheduler.proxy.address"] = address;
return properties;
}
public IScheduler GetScheduler()
{
return _scheduler;
}
public DataTable GetJobs()
{
DataTable table = new DataTable();
table.Columns.Add("GroupName");
table.Columns.Add("JobName");
table.Columns.Add("JobDescription");
table.Columns.Add("TriggerName");
table.Columns.Add("TriggerGroupName");
table.Columns.Add("TriggerType");
table.Columns.Add("TriggerState");
table.Columns.Add("NextFireTime");
table.Columns.Add("PreviousFireTime");
var jobGroups = GetScheduler().GetJobGroupNames();
foreach (string group in jobGroups)
{
var groupMatcher = GroupMatcher<JobKey>.GroupContains(group);
var jobKeys = GetScheduler().GetJobKeys(groupMatcher);
foreach (var jobKey in jobKeys)
{
var detail = GetScheduler().GetJobDetail(jobKey);
var triggers = GetScheduler().GetTriggersOfJob(jobKey);
foreach (ITrigger trigger in triggers)
{
DataRow row = table.NewRow();
row["GroupName"] = group;
row["JobName"] = jobKey.Name;
row["JobDescription"] = detail.Description;
row["TriggerName"] = trigger.Key.Name;
row["TriggerGroupName"] = trigger.Key.Group;
row["TriggerType"] = trigger.GetType().Name;
row["TriggerState"] = GetScheduler().GetTriggerState(trigger.Key);
DateTimeOffset? nextFireTime = trigger.GetNextFireTimeUtc();
if (nextFireTime.HasValue)
{
row["NextFireTime"] = TimeZone.CurrentTimeZone.ToLocalTime(nextFireTime.Value.DateTime);
}


DateTime? previousFireTime = trigger.GetPreviousFireTimeUtc();
if (previousFireTime != null)
{
row["PreviousFireTime"] = TimeZone.CurrentTimeZone.ToLocalTime((DateTime)previousFireTime);
}
DateTimeOffset? previousFireTime = trigger.GetPreviousFireTimeUtc();
if (previousFireTime.HasValue)
{
row["PreviousFireTime"] = TimeZone.CurrentTimeZone.ToLocalTime(previousFireTime.Value.DateTime);
}


table.Rows.Add(row);
}
}
}
return table;
}
table.Rows.Add(row);
}
}
}
return table;
}


public void ScheduleOneTimeJob(Type jobType, JobDataMap dataMap, int clientID)
{
string name = string.Format("{0}-{1}", jobType.Name, clientID);
string group = clientID.ToString();
JobDetail jobDetail = new JobDetail(name, group, jobType);
jobDetail.Description = "One time job";
jobDetail.Durable = false;
jobDetail.Group = group;
jobDetail.JobDataMap = dataMap;
jobDetail.JobType = jobType;
jobDetail.Name = name;
jobDetail.Volatile = true;
SimpleTrigger trigger = new SimpleTrigger();
trigger.Name = name;
trigger.Group = group;
trigger.StartTimeUtc = DateTime.UtcNow;
trigger.RepeatCount = 0;
trigger.RepeatInterval = TimeSpan.Zero;
GetScheduler().ScheduleJob(jobDetail, trigger);
}
public void ScheduleOneTimeJob(Type jobType, JobDataMap dataMap, int clientID)
{
string name = string.Format("{0}-{1}", jobType.Name, clientID);
string group = clientID.ToString();
IJobDetail jobDetail = JobBuilder.
NewJob().
OfType(jobType).
WithIdentity(name, group).
WithDescription("One time job").
UsingJobData(dataMap).Build();
ITrigger trigger = TriggerBuilder.
Create().
ForJob(jobDetail).
WithIdentity(name, group).
WithSchedule(SimpleScheduleBuilder.Create().WithRepeatCount(0).WithInterval(TimeSpan.Zero)).
StartNow().Build();
GetScheduler().ScheduleJob(jobDetail, trigger);
}


private ISchedulerFactory _schedulerFactory;
private ISchedulerFactory _schedulerFactory;


private IScheduler _scheduler;
private IScheduler _scheduler;


public DataTable GetRunningJobs()
{
DataTable table = new DataTable();
table.Columns.Add("JobName", typeof(string));
table.Columns.Add("RunTime", typeof(int));
try
{
IList jobs = GetScheduler().GetCurrentlyExecutingJobs();
foreach (JobExecutionContext context in jobs)
{
DataRow row = table.NewRow();
row["JobName"] = context.JobDetail.Name;
row["RunTime"] = (DateTime.Now.ToUniversalTime() - (DateTime)context.FireTimeUtc).TotalMinutes;
table.Rows.Add(row);
}
}
catch (Exception ex)
{
//TODO: Let the user know we couldn't load the running jobs.
}
public DataTable GetRunningJobs()
{
DataTable table = new DataTable();
table.Columns.Add("JobName", typeof(string));
table.Columns.Add("RunTime", typeof(int));
try
{
var contexts = GetScheduler().GetCurrentlyExecutingJobs();
foreach (var context in contexts)
{
DataRow row = table.NewRow();
row["JobName"] = context.JobDetail.Key.Name;
row["RunTime"] = (DateTime.Now.ToUniversalTime() - ((DateTimeOffset)context.FireTimeUtc).DateTime).TotalMinutes;
table.Rows.Add(row);
}
}
catch (Exception ex)
{
//TODO: Let the user know we couldn't load the running jobs.
}


return table;
}
return table;
}


public void BackupToFile(System.IO.FileInfo file)
{
IScheduler scheduler = GetScheduler();
string[] jobGroupNames = scheduler.JobGroupNames;
List<JobDetail> jobDetails = new List<JobDetail>();
foreach (var jobGroup in jobGroupNames)
{
string[] jobNames = scheduler.GetJobNames(jobGroup);
foreach (var jobName in jobNames)
{
jobDetails.Add(scheduler.GetJobDetail(jobName, jobGroup));
}
}
writeToFile(file, jobDetails);
public void BackupToFile(System.IO.FileInfo file)
{
IScheduler scheduler = GetScheduler();
string[] jobGroupNames = scheduler.JobGroupNames;
List<IJobDetail> jobDetails = new List<IJobDetail>();
foreach (var jobGroup in jobGroupNames)
{
string[] jobNames = scheduler.GetJobNames(jobGroup);
foreach (var jobName in jobNames)
{
jobDetails.Add(scheduler.GetJobDetail(jobName, jobGroup));
}
}
writeToFile(file, jobDetails);


}
}


private void writeToFile(System.IO.FileInfo file, List<JobDetail> jobDetails)
{
using (StreamWriter writer = file.CreateText())
{
XNamespace ns = "http://quartznet.sourceforge.net/JobSchedulingData";
XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes")
, new XElement(ns + "quartz"
, new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance")
, new XAttribute("version", "1.0")
, new XAttribute("overwrite-existing-jobs", "true")
)
);
foreach (JobDetail detail in jobDetails)
{
doc.Root.Add(
new XElement(ns + "job"
, new XElement(ns + "job-detail"
, new XElement(ns + "name", detail.Name)
, new XElement(ns + "group", detail.Group)
, new XElement(ns + "description", detail.Description)
, new XElement(ns + "job-type", detail.JobType.FullName + "," + detail.JobType.Assembly.FullName)
, new XElement(ns + "volatile", detail.Volatile)
, new XElement(ns + "durable", detail.Durable)
, new XElement(ns + "recover", detail.RequestsRecovery)
, getJobDataMap(ns, detail.JobDataMap)
)
, getTriggers(ns, detail)
)
);
}
writer.Write(doc);
writer.Flush();
writer.Close();
}
}
private void writeToFile(System.IO.FileInfo file, List<IJobDetail> jobDetails)
{
using (StreamWriter writer = file.CreateText())
{
XNamespace ns = "http://quartznet.sourceforge.net/JobSchedulingData";
XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes")
, new XElement(ns + "quartz"
, new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance")
, new XAttribute("version", "1.0")
, new XAttribute("overwrite-existing-jobs", "true")
)
);
foreach (JobDetail detail in jobDetails)
{
doc.Root.Add(
new XElement(ns + "job"
, new XElement(ns + "job-detail"
, new XElement(ns + "name", detail.Name)
, new XElement(ns + "group", detail.Group)
, new XElement(ns + "description", detail.Description)
, new XElement(ns + "job-type", detail.JobType.FullName + "," + detail.JobType.Assembly.FullName)
, new XElement(ns + "volatile", detail.Volatile)
, new XElement(ns + "durable", detail.Durable)
, new XElement(ns + "recover", detail.RequestsRecovery)
, getJobDataMap(ns, detail.JobDataMap)
)
, getTriggers(ns, detail)
)
);
}
writer.Write(doc);
writer.Flush();
writer.Close();
}
}


private XElement getJobDataMap(XNamespace ns, JobDataMap jobDataMap)
{
XElement map = new XElement(ns + "job-data-map");
foreach (var key in jobDataMap.GetKeys())
{
map.Add(new XElement(ns + "entry"
, new XElement(ns + "key", key)
, new XElement(ns + "value", jobDataMap[key])
)
);
}
private XElement getJobDataMap(XNamespace ns, JobDataMap jobDataMap)
{
XElement map = new XElement(ns + "job-data-map");
foreach (var key in jobDataMap.GetKeys())
{
map.Add(new XElement(ns + "entry"
, new XElement(ns + "key", key)
, new XElement(ns + "value", jobDataMap[key])
)
);
}


return map;
}
return map;
}


private XElement[] getTriggers(XNamespace ns, JobDetail detail)
{
Trigger[] triggers = _scheduler.GetTriggersOfJob(detail.Name, detail.Group);
XElement[] elements = new XElement[triggers.Length];
for (int i = 0; i < triggers.Length; i++)
{
elements[i] = new XElement(ns + "trigger");
if (triggers[i] is SimpleTrigger)
{
elements[i].Add(getSimpleTrigger(ns, (SimpleTrigger)triggers[i]));
}
else if (triggers[i] is CronTrigger)
{
elements[i].Add(getCronTrigger(ns, (CronTrigger)triggers[i]));
}
}
return elements;
}
private XElement[] getTriggers(XNamespace ns, IJobDetail detail)
{
var triggers = _scheduler.GetTriggersOfJob(detail.Key);
XElement[] elements = new XElement[triggers.Count];
int i = 0;
foreach (var trigger in triggers)
{
elements[i] = new XElement(ns + "trigger");
if (triggers[i] is SimpleTriggerImpl)
{
elements[i].Add(getSimpleTrigger(ns, (SimpleTriggerImpl)triggers[i]));
}
else if (triggers[i] is CronTriggerImpl)
{
elements[i].Add(getCronTrigger(ns, (CronTriggerImpl)triggers[i]));
}
i++;
}
return elements;
}


private XElement getCronTrigger(XNamespace ns, CronTrigger trigger)
{
XElement cronTrigger = new XElement(ns + "cron");
addCommonTriggerData(ns, cronTrigger, trigger);
cronTrigger.Add(
new XElement(ns + "cron-expression", trigger.CronExpressionString)
);
return cronTrigger;
}
private XElement getCronTrigger(XNamespace ns, CronTriggerImpl trigger)
{
XElement cronTrigger = new XElement(ns + "cron");
addCommonTriggerData(ns, cronTrigger, trigger);
cronTrigger.Add(
new XElement(ns + "cron-expression", trigger.CronExpressionString)
);
return cronTrigger;
}


private void addCommonTriggerData(XNamespace ns, XElement rootTriggerElement, Trigger trigger)
{
rootTriggerElement.Add(
new XElement(ns + "name", trigger.Name)
, new XElement(ns + "group", trigger.Group)
, new XElement(ns + "description", trigger.Description)
, new XElement(ns + "misfire-instruction", getMisfireInstructionText(trigger))
, new XElement(ns + "volatile", trigger.Volatile)
, new XElement(ns + "job-name", trigger.JobName)
, new XElement(ns + "job-group", trigger.JobGroup)
);
}
private void addCommonTriggerData(XNamespace ns, XElement rootTriggerElement, AbstractTrigger trigger)
{
rootTriggerElement.Add(
new XElement(ns + "name", trigger.Name)
, new XElement(ns + "group", trigger.Group)
, new XElement(ns + "description", trigger.Description)
, new XElement(ns + "misfire-instruction", getMisfireInstructionText(trigger))
//, new XElement(ns + "volatile", trigger.Volatile)
, new XElement(ns + "job-name", trigger.JobName)
, new XElement(ns + "job-group", trigger.JobGroup)
);
}


private string getMisfireInstructionText(Trigger trigger)
{
if (trigger is CronTrigger)
{
return getCronTriggerMisfireInstructionText(trigger.MisfireInstruction);
}
return getSimpleTriggerMisfireInstructionText(trigger.MisfireInstruction);
}
private string getMisfireInstructionText(AbstractTrigger trigger)
{
if (trigger is CronTriggerImpl)
{
return getCronTriggerMisfireInstructionText(trigger.MisfireInstruction);
}
return getSimpleTriggerMisfireInstructionText(trigger.MisfireInstruction);
}


private string getSimpleTriggerMisfireInstructionText(int misfireInstruction)
{
switch (misfireInstruction)
{
case 0:
return "SmartPolicy";
case 1:
return "FireNow";
case 2:
return "RescheduleNowWithExistingRepeatCount";
case 3:
return "RescheduleNowWithRemainingRepeatCount";
case 4:
return "RescheduleNextWithRemainingCount";
case 5:
return "RescheduleNextWithExistingCount";
default:
throw new ArgumentOutOfRangeException(string.Format("{0} is not a supported misfire instruction for SimpleTrigger See Quartz.MisfireInstruction for more details.", misfireInstruction));
}
}
private string getSimpleTriggerMisfireInstructionText(int misfireInstruction)
{
switch (misfireInstruction)
{
case 0:
return "SmartPolicy";
case 1:
return "FireNow";
case 2:
return "RescheduleNowWithExistingRepeatCount";
case 3:
return "RescheduleNowWithRemainingRepeatCount";
case 4:
return "RescheduleNextWithRemainingCount";
case 5:
return "RescheduleNextWithExistingCount";
default:
throw new ArgumentOutOfRangeException(string.Format("{0} is not a supported misfire instruction for SimpleTrigger See Quartz.MisfireInstruction for more details.", misfireInstruction));
}
}


private string getCronTriggerMisfireInstructionText(int misfireInstruction)
{
switch (misfireInstruction)
{
case 0:
return "SmartPolicy";
case 1:
return "FireOnceNow";
case 2:
return "DoNothing";
default:
throw new ArgumentOutOfRangeException(string.Format("{0} is not a supported misfire instruction for CronTrigger See Quartz.MisfireInstruction for more details.", misfireInstruction));
}
}
private string getCronTriggerMisfireInstructionText(int misfireInstruction)
{
switch (misfireInstruction)
{
case 0:
return "SmartPolicy";
case 1:
return "FireOnceNow";
case 2:
return "DoNothing";
default:
throw new ArgumentOutOfRangeException(string.Format("{0} is not a supported misfire instruction for CronTrigger See Quartz.MisfireInstruction for more details.", misfireInstruction));
}
}


private XElement getSimpleTrigger(XNamespace ns, SimpleTrigger trigger)
{
XElement simpleTrigger = new XElement(ns + "simple");
addCommonTriggerData(ns, simpleTrigger, trigger);
simpleTrigger.Add(
new XElement(ns + "repeat-count", trigger.RepeatCount)
, new XElement(ns + "repeat-interval", trigger.RepeatInterval.Milliseconds)
);
return simpleTrigger;
}
}
private XElement getSimpleTrigger(XNamespace ns, SimpleTriggerImpl trigger)
{
XElement simpleTrigger = new XElement(ns + "simple");
addCommonTriggerData(ns, simpleTrigger, trigger);
simpleTrigger.Add(
new XElement(ns + "repeat-count", trigger.RepeatCount)
, new XElement(ns + "repeat-interval", trigger.RepeatInterval.Milliseconds)
);
return simpleTrigger;
}
}
} }

+ 11
- 10
ClickForensics.Quartz.Manager/TriggerNode.cs View File

@@ -4,17 +4,18 @@ using System.Linq;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using Quartz; using Quartz;
using Quartz.Impl.Triggers;


namespace ClickForensics.Quartz.Manager namespace ClickForensics.Quartz.Manager
{ {
public class TriggerNode : TreeNode
{
public TriggerNode(Trigger trigger)
{
Text = trigger.Name;
Trigger = trigger;
}
public Trigger Trigger { get; set; }
}
public class TriggerNode : TreeNode
{
public TriggerNode(AbstractTrigger trigger)
{
Text = trigger.Name;
Trigger = trigger;
}
public AbstractTrigger Trigger { get; set; }
}
} }

BIN
lib/Quartz.dll View File


Loading…
Cancel
Save